Re: [PATCH] misc: rtsx: Add support new chip rts5228 mmc: rtsx: Add support MMC_CAP2_NO_MMC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[+cc Puranjay, for LTR issues, original posting at
https://lore.kernel.org/r/20200706070259.32565-1-ricky_wu@xxxxxxxxxxx]

I've complained about some of this stuff before, but we haven't really
made any progress yet:

  https://lore.kernel.org/lkml/20171214222522.GL30595@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/

On Mon, Jul 06, 2020 at 03:02:59PM +0800, ricky_wu@xxxxxxxxxxx wrote:
> From: Ricky Wu <ricky_wu@xxxxxxxxxxx>
> 
> In order to support new chip rts5228, the definitions of some internal
> registers and workflow have to be modified.
> Added rts5228.c rts5228.h for independent functions of the new chip rts5228

> +static void rts5228_init_from_cfg(struct rtsx_pcr *pcr)
> +{
> +	u32 lval;
> +	struct rtsx_cr_option *option = &pcr->option;
> +
> +	rtsx_pci_read_config_dword(pcr, PCR_ASPM_SETTING_REG1, &lval);
> +
> +
> +	if (0 == (lval & 0x0F))
> +		rtsx_pci_enable_oobs_polling(pcr);
> +	else
> +		rtsx_pci_disable_oobs_polling(pcr);
> +
> +	if (lval & ASPM_L1_1_EN_MASK)
> +		rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
> +	else
> +		rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN);
> +
> +	if (lval & ASPM_L1_2_EN_MASK)
> +		rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
> +	else
> +		rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN);
> +
> +	if (lval & PM_L1_1_EN_MASK)
> +		rtsx_set_dev_flag(pcr, PM_L1_1_EN);
> +	else
> +		rtsx_clear_dev_flag(pcr, PM_L1_1_EN);
> +
> +	if (lval & PM_L1_2_EN_MASK)
> +		rtsx_set_dev_flag(pcr, PM_L1_2_EN);
> +	else
> +		rtsx_clear_dev_flag(pcr, PM_L1_2_EN);

This looks like a bunch of driver-specific #defines that should be
using the PCI core #defines instead (PCI_L1SS_CTL1_ASPM_L1_1,
PCI_L1SS_CTL1_ASPM_L1_2, etc).

rtsx_pci_read_config_dword() adds very little value and obscures the
code unnecessarily.

PCR_ASPM_SETTING_REG1 probably should be removed and replaced with
something like pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS).

> +	rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0);
> +	if (option->ltr_en) {
> +		u16 val;
> +
> +		pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val);
> +		if (val & PCI_EXP_DEVCTL2_LTR_EN) {
> +			option->ltr_enabled = true;
> +			option->ltr_active = true;
> +			rtsx_set_ltr_latency(pcr, option->ltr_active_latency);

I do not believe this LTR programming is correct.  But I'd be glad to
be corrected with specific references to the spec.

One reason I don't think it's correct is because PCIe r5.0, sec 6.18,
says LTR must not be enabled unless the Root Complex and all
intermediate Switches indicate support for LTR.  I don't see any
checking for that here.

I *assume* that rtsx_set_ltr_latency() sets values in the LTR
Extended Capability.  That should be done with
pci_write_config_word(), not with rtsx_pci_write_register() as is done
in rtsx_comm_set_ltr_latency().  But maybe rtsx_set_ltr_latency()
isn't doing what I think it is.

I think the values programmed into the LTR Capability depend on some
platform-specific values that can only be learned from an ACPI _DSM;
see the PCI Firmware spec, v3.2, sec 4.6.6.

It looks like option->ltr_active_latency is always
LTR_ACTIVE_LATENCY_DEF (0x883C).  How did you derive that value?

All the LTR programming should be done by the PCI core.  The PCI core
does some of that, but not all.  We should work on getting support
done instead of spreading it around in drivers.

> +static void rts5228_enable_aspm(struct rtsx_pcr *pcr, bool enable)
> +{
> +	u8 mask, val;
> +
> +	if (pcr->aspm_enabled == enable)
> +		return;
> +
> +	mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;
> +	val = FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;
> +	val |= (pcr->aspm_en & 0x02);
> +	rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
> +	pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL,
> +					   PCI_EXP_LNKCTL_ASPMC, pcr->aspm_en);
> +	pcr->aspm_enabled = enable;

ASPM configuration should also be done by the PCI core.

Correct ASPM configuration can only be done by looking at *both* ends
of the link.  The PCI core is in a position to do that, but individual
drivers really are not.

Bjorn



[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux