diff --git a/Marlin/src/feature/touch/xpt2046.cpp b/Marlin/src/feature/touch/xpt2046.cpp
index 7f9a718604deee17790565386bab2e4ebf62b436..463034d96b987313b37cbea8d2b91c65f1f8f6a6 100644
--- a/Marlin/src/feature/touch/xpt2046.cpp
+++ b/Marlin/src/feature/touch/xpt2046.cpp
@@ -25,6 +25,29 @@
 #include "../../inc/MarlinConfig.h"
 #include "../../lcd/dogm/ultralcd_DOGM.h" // for LCD_FULL_PIXEL_WIDTH, etc.
 
+/*
+ * Draw and Touch processing
+ *
+ *      LCD_PIXEL_WIDTH/HEIGHT (128x64) is the (emulated DOGM) Pixel Drawing resolution.
+ *   TOUCH_SCREEN_WIDTH/HEIGHT (320x240) is the Touch Area resolution.
+ * LCD_FULL_PIXEL_WIDTH/HEIGHT (320x240 or 480x320) is the Actual (FSMC) Display resolution.
+ *
+ *  - All native (u8g) drawing is done in LCD_PIXEL_* (128x64)
+ *  - The DOGM pixels are is upscaled 2-3x (as needed) for display.
+ *  - Touch coordinates use TOUCH_SCREEN_* resolution and are converted to
+ *    click and scroll-wheel events (emulating of a common DOGM display).
+ *
+ *  TOUCH_SCREEN resolution exists to fit our calibration values. The original touch code was made
+ *  and originally calibrated for 320x240. If you decide to change the resolution of the touch code,
+ *  new calibration values will be needed.
+ *
+ *  The Marlin menus are drawn scaled in the upper region of the screen. The bottom region (in a
+ *  fixed location in TOUCH_SCREEN* coordinate space) is used for 4 general-purpose buttons to
+ *  navigate and select menu items. Both regions are touchable.
+ *
+ * The Marlin screen touchable area starts at LCD_PIXEL_OFFSET_X/Y (translated to SCREEN_START_LEFT/TOP)
+ * and spans LCD_PIXEL_WIDTH/HEIGHT (scaled to SCREEN_WIDTH/HEIGHT).
+ */
 // Touch screen resolution independent of display resolution
 #define TOUCH_SCREEN_HEIGHT 240
 #define TOUCH_SCREEN_WIDTH 320
@@ -33,8 +56,13 @@
 #define BUTTON_AREA_TOP 175
 #define BUTTON_AREA_BOT 234
 
-#define SCREEN_START_TOP ((LCD_PIXEL_OFFSET_Y) * (TOUCH_SCREEN_HEIGHT) / (LCD_FULL_PIXEL_HEIGHT))
-#define TOUCHABLE_Y_HEIGHT (BUTTON_AREA_TOP - (SCREEN_START_TOP))
+#define SCREEN_START_TOP  ((LCD_PIXEL_OFFSET_Y) * (TOUCH_SCREEN_HEIGHT) / (LCD_FULL_PIXEL_HEIGHT))
+#define SCREEN_START_LEFT ((LCD_PIXEL_OFFSET_X) * (TOUCH_SCREEN_WIDTH) / (LCD_FULL_PIXEL_WIDTH))
+#define SCREEN_HEIGHT     ((LCD_PIXEL_HEIGHT * FSMC_UPSCALE) * (TOUCH_SCREEN_HEIGHT) / (LCD_FULL_PIXEL_HEIGHT))
+#define SCREEN_WIDTH      ((LCD_PIXEL_WIDTH * FSMC_UPSCALE) * (TOUCH_SCREEN_WIDTH) / (LCD_FULL_PIXEL_WIDTH))
+
+#define TOUCHABLE_Y_HEIGHT  SCREEN_HEIGHT
+#define TOUCHABLE_X_WIDTH  SCREEN_WIDTH
 
 #ifndef TOUCH_INT_PIN
   #define TOUCH_INT_PIN  -1
@@ -98,10 +126,10 @@ uint8_t XPT2046::read_buttons() {
          : WITHIN(x, 242, 305) ? EN_C
          : 0;
 
-  if (x > TOUCH_SCREEN_WIDTH || !WITHIN(y, SCREEN_START_TOP, BUTTON_AREA_TOP)) return 0;
+  if (x > TOUCH_SCREEN_WIDTH || !WITHIN(y, SCREEN_START_TOP, SCREEN_START_TOP + SCREEN_HEIGHT)) return 0;
 
   // Column and row above BUTTON_AREA_TOP
-  int8_t col = x * (LCD_WIDTH) / (TOUCH_SCREEN_WIDTH),
+  int8_t col = (x - (SCREEN_START_LEFT)) * (LCD_WIDTH) / (TOUCHABLE_X_WIDTH),
          row = (y - (SCREEN_START_TOP)) * (LCD_HEIGHT) / (TOUCHABLE_Y_HEIGHT);
 
   // Send the touch to the UI (which will simulate the encoder wheel)
diff --git a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
index 7c7021a2437c8527bc69ff55bcb6ee1778ca9759..20fd44f5801f856e6c0862ec72cc97e4e66c5724 100644
--- a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
+++ b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
@@ -73,10 +73,6 @@
   extern void LCD_IO_WriteMultiple(uint16_t color, uint32_t count);
 #endif
 
-#ifndef FSMC_UPSCALE
-  #define FSMC_UPSCALE 2
-#endif
-
 #define WIDTH LCD_PIXEL_WIDTH
 #define HEIGHT LCD_PIXEL_HEIGHT
 #define PAGE_HEIGHT 8
diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.h b/Marlin/src/lcd/dogm/ultralcd_DOGM.h
index 7a7a4df7457b38c9a3f0de3615b2b703a0431efc..e96d4d7b071bd302f29127137e91dacff555e84a 100644
--- a/Marlin/src/lcd/dogm/ultralcd_DOGM.h
+++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.h
@@ -254,4 +254,8 @@
 #define INFO_FONT_HEIGHT (INFO_FONT_ASCENT + INFO_FONT_DESCENT)
 #define INFO_FONT_WIDTH   6
 
+#ifndef FSMC_UPSCALE
+  #define FSMC_UPSCALE 2
+#endif
+
 extern U8G_CLASS u8g;
diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp
index 4c416093aed8629637cd193e39cb2db6e7c8f009..6b52f64b90414e3364d9f19dbc8d15a69c3ec2f9 100644
--- a/Marlin/src/lcd/ultralcd.cpp
+++ b/Marlin/src/lcd/ultralcd.cpp
@@ -1455,7 +1455,7 @@ void MarlinUI::update() {
         encoderDiff = ENCODER_PULSES_PER_STEP * ydir;
       else if (screen_items > 0) {
         // Last 3 cols act as a scroll :-)
-        if (col > (LCD_WIDTH) - 3)
+        if (col > (LCD_WIDTH) - 5)
           // 2 * LCD_HEIGHT to scroll to bottom of next page. (LCD_HEIGHT would only go 1 item down.)
           encoderDiff = ENCODER_PULSES_PER_STEP * (encoderLine - encoderTopLine + 2 * (LCD_HEIGHT)) * ydir;
         else