Posting a followup in the hopes that it helps someone else in the future. The root cause issue turned out to be an undocumented requirement with the FT811 that the REG_HCYCLE value must be greater than the sum of the REG_HOFFSET and REG_HSIZE values (same is true for the vertical timing). I actually did have the ST7789 configured properly and running, but FT811 refused to perform the swap and draw a new screen unless the above condition was true.
For the actual ST7789 setup, I used a mux to share the CS between the display and the FT811, and this init code. I configured the display as 4 line 8 bit serial II (IM[3:0] = 1110) which required another GPIO to toggle the D/CX line, but any serial config should work, with 9-bit 3 wire being the simplest. Some of these delays are arbitrary and can likely be tightened up:
Set RESX low
50ms delay
set RESX high
50ms delay
set MADCTL to 0x00
set COLMOD to 0x66 (18-bit RGB mode)
send INVON command
set RAMCTRL to 0x11, 0xC2
set RGBCTRL to 0x40, 0x08, 0x14
send command DISPON
100ms delay
send command SLPOUT
100ms delay
For configruing the FT811:
// HORIZONTAL TIMING
#define hfp 38
#define hsw 10
#define hbp 10
#define h_active 240
#define h_total (hfp + hsw + hbp + h_active+1) //+1 to make it actually swap
// VERTICAL TIMING
#define vfp 8
#define vsw 4
#define vbp 4
#define v_active 320
#define v_total (vfp + vsw + vbp + v_active+1) //+1 to make it actually swap
//Screen Settings
#define DISPLAY_HCYCLE h_total //total pixels/line
#define DISPLAY_HOFFSET (hfp + hsw + hbp) //(FP + sync width before active)
#define DISPLAY_HSYNC0 hfp //(sync pulse starts after FP)
#define DISPLAY_HSYNC1 (hfp + hsw) //(sync pulse ends)
#define DISPLAY_VCYCLE v_total //total lines/frame
#define DISPLAY_VOFFSET (vfp + vsw + vbp) //(FP + sync width before active)
#define DISPLAY_VSYNC0 vfp //(sync pulse starts after FP)
#define DISPLAY_VSYNC1 (vfp+vsw) //(sync pulse ends)
#define DISPLAY_PCLK_POL 0 //rising edge output
#define DISPLAY_CSPREAD 1
#define DISPLAY_WIDTH h_active
#define DISPLAY_HEIGHT v_active
#define PCLK_DIV 3 //16Mhz when main clock set to 48MHz
For the actual ST7789 setup, I used a mux to share the CS between the display and the FT811, and this init code. I configured the display as 4 line 8 bit serial II (IM[3:0] = 1110) which required another GPIO to toggle the D/CX line, but any serial config should work, with 9-bit 3 wire being the simplest. Some of these delays are arbitrary and can likely be tightened up:
Set RESX low
50ms delay
set RESX high
50ms delay
set MADCTL to 0x00
set COLMOD to 0x66 (18-bit RGB mode)
send INVON command
set RAMCTRL to 0x11, 0xC2
set RGBCTRL to 0x40, 0x08, 0x14
send command DISPON
100ms delay
send command SLPOUT
100ms delay
For configruing the FT811:
// HORIZONTAL TIMING
#define hfp 38
#define hsw 10
#define hbp 10
#define h_active 240
#define h_total (hfp + hsw + hbp + h_active+1) //+1 to make it actually swap
// VERTICAL TIMING
#define vfp 8
#define vsw 4
#define vbp 4
#define v_active 320
#define v_total (vfp + vsw + vbp + v_active+1) //+1 to make it actually swap
//Screen Settings
#define DISPLAY_HCYCLE h_total //total pixels/line
#define DISPLAY_HOFFSET (hfp + hsw + hbp) //(FP + sync width before active)
#define DISPLAY_HSYNC0 hfp //(sync pulse starts after FP)
#define DISPLAY_HSYNC1 (hfp + hsw) //(sync pulse ends)
#define DISPLAY_VCYCLE v_total //total lines/frame
#define DISPLAY_VOFFSET (vfp + vsw + vbp) //(FP + sync width before active)
#define DISPLAY_VSYNC0 vfp //(sync pulse starts after FP)
#define DISPLAY_VSYNC1 (vfp+vsw) //(sync pulse ends)
#define DISPLAY_PCLK_POL 0 //rising edge output
#define DISPLAY_CSPREAD 1
#define DISPLAY_WIDTH h_active
#define DISPLAY_HEIGHT v_active
#define PCLK_DIV 3 //16Mhz when main clock set to 48MHz