aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/816-sdhc-0003-LF-605-mmc-sdhci-of-esdhc-update-tuning-erratum-A-00.patch
blob: f9722b36982f7cec101d5623f37fdb5d54ef2f29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
From f3d460fb85677a5f62324771e5715ceb11726ecc Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Thu, 12 Dec 2019 15:52:19 +0800
Subject: [PATCH] LF-605 mmc: sdhci-of-esdhc: update tuning erratum A-008171

There is an official update for eSDHC tuning erratum A-008171.
This patch is to implement the changes,
- Affect all revisions of SoC.
- Changes for tuning window checking.
- Hardware hits a new condition that tuning succeeds although
  the eSDHC might not have tuned properly for type2 SoCs
  (soc_tuning_erratum_type2[] array in driver). So check
  tuning window after tuning succeeds.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
---
 drivers/mmc/host/sdhci-of-esdhc.c | 39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)

--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -895,20 +895,20 @@ static int esdhc_signal_voltage_switch(s
 }
 
 static struct soc_device_attribute soc_tuning_erratum_type1[] = {
-	{ .family = "QorIQ T1023", .revision = "1.0", },
-	{ .family = "QorIQ T1040", .revision = "1.0", },
-	{ .family = "QorIQ T2080", .revision = "1.0", },
-	{ .family = "QorIQ LS1021A", .revision = "1.0", },
+	{ .family = "QorIQ T1023", },
+	{ .family = "QorIQ T1040", },
+	{ .family = "QorIQ T2080", },
+	{ .family = "QorIQ LS1021A", },
 	{ },
 };
 
 static struct soc_device_attribute soc_tuning_erratum_type2[] = {
-	{ .family = "QorIQ LS1012A", .revision = "1.0", },
-	{ .family = "QorIQ LS1043A", .revision = "1.*", },
-	{ .family = "QorIQ LS1046A", .revision = "1.0", },
-	{ .family = "QorIQ LS1080A", .revision = "1.0", },
-	{ .family = "QorIQ LS2080A", .revision = "1.0", },
-	{ .family = "QorIQ LA1575A", .revision = "1.0", },
+	{ .family = "QorIQ LS1012A", },
+	{ .family = "QorIQ LS1043A", },
+	{ .family = "QorIQ LS1046A", },
+	{ .family = "QorIQ LS1080A", },
+	{ .family = "QorIQ LS2080A", },
+	{ .family = "QorIQ LA1575A", },
 	{ },
 };
 
@@ -976,13 +976,13 @@ static void esdhc_prepare_sw_tuning(stru
 	/* Write 32'hFFFF_FFFF to IRQSTAT register */
 	sdhci_writel(host, 0xFFFFFFFF, SDHCI_INT_STATUS);
 
-	/* If TBSTAT[15:8]-TBSTAT[7:0] > 4 * div_ratio
-	 * or TBSTAT[7:0]-TBSTAT[15:8] > 4 * div_ratio,
+	/* If TBSTAT[15:8]-TBSTAT[7:0] > (4 * div_ratio) + 2
+	 * or TBSTAT[7:0]-TBSTAT[15:8] > (4 * div_ratio) + 2,
 	 * then program TBPTR[TB_WNDW_END_PTR] = 4 * div_ratio
 	 * and program TBPTR[TB_WNDW_START_PTR] = 8 * div_ratio.
 	 */
 
-	if (abs(start_ptr - end_ptr) > (4 * esdhc->div_ratio)) {
+	if (abs(start_ptr - end_ptr) > (4 * esdhc->div_ratio + 2)) {
 		*window_start = 8 * esdhc->div_ratio;
 		*window_end = 4 * esdhc->div_ratio;
 	} else {
@@ -1066,6 +1066,19 @@ static int esdhc_execute_tuning(struct m
 		if (ret)
 			break;
 
+		/* For type2 affected platforms of the tuning erratum,
+		 * tuning may succeed although eSDHC might not have
+		 * tuned properly. Need to check tuning window.
+		 */
+		if (esdhc->quirk_tuning_erratum_type2 &&
+		    !host->tuning_err) {
+			esdhc_tuning_window_ptr(host, &window_start,
+						&window_end);
+			if (abs(window_start - window_end) >
+			    (4 * esdhc->div_ratio + 2))
+				host->tuning_err = -EAGAIN;
+		}
+
 		/* If HW tuning fails and triggers erratum,
 		 * try workaround.
 		 */
lass="c1">// //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // In Indirect Mode, a copy of the framebuffer is kept in system memory. // A timer periodically writes this copy to the "real" framebuffer in // hardware. This copy is called a virtual framebuffer. //---------------------------------------------------------------------------- // Global structures used by s1d13521fb frame buffer code //---------------------------------------------------------------------------- typedef struct { volatile unsigned char *RegAddr; unsigned RegAddrMappedSize; volatile unsigned char *DataPort; unsigned DataPortSzie; volatile unsigned char *CommandPort; unsigned CommandPortSzie; u32 VirtualFramebufferAddr; int blank_mode; u32 pseudo_palette[16]; }FB_INFO_S1D13521; extern struct fb_fix_screeninfo s1d13521fb_fix; extern struct fb_info s1d13521_fb; extern FB_INFO_S1D13521 s1d13521fb_info; extern char *s1d13521fb_version; //----------------------------------------------------------------------------- // Global Function Prototypes //----------------------------------------------------------------------------- #ifdef CONFIG_FB_EPSON_PROC int __devinit s1d13521proc_init(void); void __devexit s1d13521proc_terminate(void); #endif #ifdef CONFIG_FB_EPSON_PCI int __devinit s1d13521pci_init(long *physicalAddress); void __devexit s1d13521pci_terminate(void); #endif //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // // // //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ typedef struct TAG_ST_A_GPIO_INFO{ const UINT32 Info; const char *Name; } ST_A_GPIO_INFO, *PST_A_GPIO_INFO; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // // // //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ typedef enum { _EPSON_ERROR_SUCCESS=0, _EPSON_ERROR_NOT_READY, _EPSON_ERROR_TIMEOUT, _EPSON_ERROR_WRITE_FAIL, } EN_EPSON_ERROR_CODE; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // // // //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ typedef struct TAG_ST_DESC_ACCESS_BUF { UINT32 Len; PUINT pData; } ST_DESC_ACCESS_BUF, *PST_DESC_ACCESS_BUF; #pragma pack(1) typedef struct TAG_ST_COMMAND_PACKAGE { ST_DESC_ACCESS_BUF Write; ST_DESC_ACCESS_BUF Read; UINT16 Command; } ST_COMMAND_PACKAGE, *PST_COMMAND_PACKAGE; #pragma pack() //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // // // //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ typedef struct TAG_ST_PARTIAL_RECT { UINT16 StartX; UINT16 StartY; UINT16 Width; UINT16 Height; } ST_PARTIAL_RECT, *PST_PARTIAL_RECT; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // // // //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ int __devinit s1d13521if_InterfaceInit(FB_INFO_S1D13521 *info); void __devexit s1d13521if_InterfaceTerminate(FB_INFO_S1D13521 *info); int BusIssueCmd(unsigned ioctlcmd,s1d13521_ioctl_cmd_params *params,int numparams); void BusIssueWriteBuf(u16 *ptr16, unsigned copysize16); void BusIssueReadBuf(u16 *ptr16, unsigned copysize16); u16 BusIssueReadReg(u16 Index); EN_EPSON_ERROR_CODE BusIssueWriteReg(u16 Index, u16 Value); EN_EPSON_ERROR_CODE BusIssueWriteRegX(u16 Index, u16 Value); EN_EPSON_ERROR_CODE BusIssueCmdX(UINT16 Cmd); EN_EPSON_ERROR_CODE BusIssueWriteRegBuf(u16 Index, PUINT16 pData, UINT32 Length); EN_EPSON_ERROR_CODE BusWaitForHRDY(void); void BusIssueDoRefreshDisplay(unsigned cmd,unsigned mode); void BusIssueInitDisplay(void); void BusIssueInitRegisters(void); int pvi_GoToSleep(void); int pvi_GoToNormal(void); // int s1d13521if_CmdPackage(PST_COMMAND_PACKAGE pCmdPkg); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // // // //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ int pvi_Init(VOID); VOID pvi_Deinit(VOID); int pvi_ioctl_NewImage(PTDisplayCommand puDisplayCommand); int pvi_ioctl_StopNewImage(PTDisplayCommand puDisplayCommand); int pvi_ioctl_DisplayImage(PTDisplayCommand puDisplayCommand); int pvi_ioctl_PartialImage(PTDisplayCommand puDisplayCommand); int pvi_ioctl_DisplayPartial(PTDisplayCommand puDisplayCommand); int pvi_ioctl_Reset(PTDisplayCommand puDisplayCommand); int pvi_ioctl_SetDepth(PTDisplayCommand puDisplayCommand); int pvi_ioctl_EraseDisplay(PTDisplayCommand puDisplayCommand); int pvi_ioctl_Rotate(PTDisplayCommand puDisplayCommand); int pvi_ioctl_Positive(PTDisplayCommand puDisplayCommand); int pvi_ioctl_Negative(PTDisplayCommand puDisplayCommand); int pvi_ioctl_GoToNormal(PTDisplayCommand puDisplayCommand); int pvi_ioctl_GoToSleep(PTDisplayCommand puDisplayCommand); int pvi_ioctl_GoToStandBy(PTDisplayCommand puDisplayCommand); int pvi_ioctl_WriteToFlash(PTDisplayCommand puDisplayCommand); int pvi_ioctl_ReadFromFlash(PTDisplayCommand puDisplayCommand); int pvi_ioctl_Init(PTDisplayCommand puDisplayCommand); int pvi_ioctl_AutoRefreshOn(PTDisplayCommand puDisplayCommand); int pvi_ioctl_AutoRefreshOff(PTDisplayCommand puDisplayCommand); int pvi_ioctl_SetRefresh(PTDisplayCommand puDisplayCommand); int pvi_ioctl_ForcedRefresh(PTDisplayCommand puDisplayCommand); int pvi_ioctl_GetRefresh(PTDisplayCommand puDisplayCommand); int pvi_ioctl_RestoreImage(PTDisplayCommand puDisplayCommand); int pvi_ioctl_ControllerVersion(PTDisplayCommand puDisplayCommand); int pvi_ioctl_SoftwareVersion(PTDisplayCommand puDisplayCommand); int pvi_ioctl_DisplaySize(PTDisplayCommand puDisplayCommand); int pvi_ioctl_GetStatus(PTDisplayCommand puDisplayCommand); int pvi_ioctl_Temperature(PTDisplayCommand puDisplayCommand); int pvi_ioctl_WriteRegister(PTDisplayCommand puDisplayCommand); int pvi_ioctl_ReadRegister(PTDisplayCommand puDisplayCommand); int pvi_SwitchCommand(PTDisplayCommand pDisplayCommand); //int Epson_displayCMD(PST_IMAGE_PGM PST); //int Epson_displayCMD_MEM(PST_IMAGE_PGM_MEM PST); //KEG 20090914 //int Epson_LoadImageArea(PTloadImageArea area); // KEG 20090814 //BOOL BusIssueFlashOperation(PS1D13532_FLASH_PACKAGE pFlashControl); BOOL BusIssueReset(void); //int ImagePGM(PST_IMAGE_PGM pPGM); VOID DeviceReset(VOID); #endif //__S1D13521FB_H__