mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	mmc: sdhci-pci-o2micro: Add HW tuning for SDR104 mode
Add HW tuning support for SD host controller in SDR104 mode Signed-off-by: Shirley Her <shirley.her@bayhubtech.com> Link: https://lore.kernel.org/r/20200721012700.8564-1-shirley.her@bayhubtech.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
		
							parent
							
								
									cdd2b76978
								
							
						
					
					
						commit
						7b7d897e88
					
				
					 1 changed files with 29 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -196,7 +196,7 @@ static void __sdhci_o2_execute_tuning(struct sdhci_host *host, u32 opcode)
 | 
			
		|||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	sdhci_send_tuning(host, MMC_SEND_TUNING_BLOCK_HS200);
 | 
			
		||||
	sdhci_send_tuning(host, opcode);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 150; i++) {
 | 
			
		||||
		u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 | 
			
		||||
| 
						 | 
				
			
			@ -305,10 +305,12 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
 | 
			
		|||
	 * This handler only implements the eMMC tuning that is specific to
 | 
			
		||||
	 * this controller.  Fall back to the standard method for other TIMING.
 | 
			
		||||
	 */
 | 
			
		||||
	if (host->timing != MMC_TIMING_MMC_HS200)
 | 
			
		||||
	if ((host->timing != MMC_TIMING_MMC_HS200) &&
 | 
			
		||||
		(host->timing != MMC_TIMING_UHS_SDR104))
 | 
			
		||||
		return sdhci_execute_tuning(mmc, opcode);
 | 
			
		||||
 | 
			
		||||
	if (WARN_ON(opcode != MMC_SEND_TUNING_BLOCK_HS200))
 | 
			
		||||
	if (WARN_ON((opcode != MMC_SEND_TUNING_BLOCK_HS200) &&
 | 
			
		||||
			(opcode != MMC_SEND_TUNING_BLOCK)))
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	/*
 | 
			
		||||
	 * Judge the tuning reason, whether caused by dll shift
 | 
			
		||||
| 
						 | 
				
			
			@ -342,6 +344,9 @@ static int sdhci_o2_execute_tuning(struct mmc_host *mmc, u32 opcode)
 | 
			
		|||
		sdhci_set_bus_width(host, current_bus_width);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sdhci_reset(host, SDHCI_RESET_CMD);
 | 
			
		||||
	sdhci_reset(host, SDHCI_RESET_DATA);
 | 
			
		||||
 | 
			
		||||
	host->flags &= ~SDHCI_HS400_TUNING;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -369,7 +374,6 @@ static void o2_pci_led_enable(struct sdhci_pci_chip *chip)
 | 
			
		|||
	scratch_32 |= O2_SD_LED_ENABLE;
 | 
			
		||||
	pci_write_config_dword(chip->pdev,
 | 
			
		||||
			       O2_SD_TEST_REG, scratch_32);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip)
 | 
			
		||||
| 
						 | 
				
			
			@ -497,6 +501,10 @@ static void sdhci_o2_enable_clk(struct sdhci_host *host, u16 clk)
 | 
			
		|||
static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)
 | 
			
		||||
{
 | 
			
		||||
	u16 clk;
 | 
			
		||||
	u8 scratch;
 | 
			
		||||
	u32 scratch_32;
 | 
			
		||||
	struct sdhci_pci_slot *slot = sdhci_priv(host);
 | 
			
		||||
	struct sdhci_pci_chip *chip = slot->chip;
 | 
			
		||||
 | 
			
		||||
	host->mmc->actual_clock = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -505,6 +513,23 @@ static void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)
 | 
			
		|||
	if (clock == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if ((host->timing == MMC_TIMING_UHS_SDR104) && (clock == 200000000)) {
 | 
			
		||||
		pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
 | 
			
		||||
 | 
			
		||||
		scratch &= 0x7f;
 | 
			
		||||
		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 | 
			
		||||
 | 
			
		||||
		pci_read_config_dword(chip->pdev, O2_SD_PLL_SETTING, &scratch_32);
 | 
			
		||||
 | 
			
		||||
		if ((scratch_32 & 0xFFFF0000) != 0x2c280000)
 | 
			
		||||
			o2_pci_set_baseclk(chip, 0x2c280000);
 | 
			
		||||
 | 
			
		||||
		pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
 | 
			
		||||
 | 
			
		||||
		scratch |= 0x80;
 | 
			
		||||
		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
 | 
			
		||||
	sdhci_o2_enable_clk(host, clk);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue