Re: [PATCH] rtc: Fix the AltCentury for AMD platforms

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

 



On 20/01/2022 12:27:39-0600, Limonciello, Mario wrote:
> On 1/11/2022 16:57, Mario Limonciello wrote:
> > Setting the century forward has been failing on AMD platforms.
> > There was a previous attempt at fixing this for family 0x17 as part of
> > commit 7ad295d5196a ("rtc: Fix the AltCentury value on AMD/Hygon
> > platform") but this was later reverted due to some problems reported
> > that appeared to stem from an FW bug on a family 0x17 desktop system.
> > 
> > The same comments mentioned in the previous commit continue to apply
> > to the newer platforms as well.
> > 
> > ```
> > MC146818 driver use function mc146818_set_time() to set register
> > RTC_FREQ_SELECT(RTC_REG_A)'s bit4-bit6 field which means divider stage
> > reset value on Intel platform to 0x7.
> > 
> > While AMD/Hygon RTC_REG_A(0Ah)'s bit4 is defined as DV0 [Reference]:
> > DV0 = 0 selects Bank 0, DV0 = 1 selects Bank 1. Bit5-bit6 is defined
> > as reserved.
> > 
> > DV0 is set to 1, it will select Bank 1, which will disable AltCentury
> > register(0x32) access. As UEFI pass acpi_gbl_FADT.century 0x32
> > (AltCentury), the CMOS write will be failed on code:
> > CMOS_WRITE(century, acpi_gbl_FADT.century).
> > 
> > Correct RTC_REG_A bank select bit(DV0) to 0 on AMD/Hygon CPUs, it will
> > enable AltCentury(0x32) register writing and finally setup century as
> > expected.
> > ```
> > 
> > However in closer examination the change previously submitted was also
> > modifying bits 5 & 6 which are declared reserved in the AMD documentation.
> > So instead modify just the DV0 bank selection bit.
> > 
> > Being cognizant that there was a failure reported before, split the code
> > change out to a static function that can also be used for exclusions if
> > any regressions such as Mikhail's pop up again.
> > 
> > Cc: Jinke Fan <fanjinke@xxxxxxxx>
> > Cc: Mikhail Gavrilov <mikhail.v.gavrilov@xxxxxxxxx>
> > Link: https://lore.kernel.org/all/CABXGCsMLob0DC25JS8wwAYydnDoHBSoMh2_YLPfqm3TTvDE-Zw@xxxxxxxxxxxxxx/
> > Link: https://www.amd.com/system/files/TechDocs/51192_Bolton_FCH_RRG.pdf
> > Signed-off-by: Raul E Rangel <rrangel@xxxxxxxxxxxx>
> > Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx>
> > ---
> >   drivers/rtc/rtc-mc146818-lib.c | 16 +++++++++++++++-
> >   include/linux/mc146818rtc.h    |  2 ++
> >   2 files changed, 17 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/rtc/rtc-mc146818-lib.c b/drivers/rtc/rtc-mc146818-lib.c
> > index dcfaf09946ee..3c8be2136703 100644
> > --- a/drivers/rtc/rtc-mc146818-lib.c
> > +++ b/drivers/rtc/rtc-mc146818-lib.c
> > @@ -120,6 +120,17 @@ unsigned int mc146818_get_time(struct rtc_time *time)
> >   }
> >   EXPORT_SYMBOL_GPL(mc146818_get_time);
> > +/* AMD systems don't allow access to AltCentury with DV1 */
> > +static bool apply_amd_register_a_behavior(void)
> > +{
> > +#ifdef CONFIG_X86
> > +	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
> > +	    boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
> > +		return true;
> > +#endif
> > +	return false;
> > +}
> > +
> >   /* Set the current date and time in the real time clock. */
> >   int mc146818_set_time(struct rtc_time *time)
> >   {
> > @@ -191,7 +202,10 @@ int mc146818_set_time(struct rtc_time *time)
> >   	save_control = CMOS_READ(RTC_CONTROL);
> >   	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
> >   	save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
> > -	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
> > +	if (apply_amd_register_a_behavior())
> > +		CMOS_WRITE((save_freq_select & ~RTC_AMD_BANK_SELECT), RTC_FREQ_SELECT);
> > +	else
> > +		CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
> >   #ifdef CONFIG_MACH_DECSTATION
> >   	CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
> > diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
> > index 0661af17a758..1e0205811394 100644
> > --- a/include/linux/mc146818rtc.h
> > +++ b/include/linux/mc146818rtc.h
> > @@ -86,6 +86,8 @@ struct cmos_rtc_board_info {
> >      /* 2 values for divider stage reset, others for "testing purposes only" */
> >   #  define RTC_DIV_RESET1	0x60
> >   #  define RTC_DIV_RESET2	0x70
> > +   /* In AMD BKDG bit 5 and 6 are reserved, bit 4 is for select dv0 bank */
> > +#  define RTC_AMD_BANK_SELECT	0x10
> >     /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
> >   # define RTC_RATE_SELECT 	0x0F
> 
> Hi Alexandre, Alessandro,
> 
> Friendly ping on this request.
> 

This was sent too close from the merge window to be applied.

> Also if it wasn't made clear in my commit message or by analyzing this code
> change, I do believe that at least part of the reason for the previous
> regression was because of mucking with reserved bits.  This patch is much
> more conservative.
> 
> In my testing I found similar behaviors from the old regression on a more
> modern platform when those bits were being touched.
> 
> Mikhail,
> 
> As you flagged the previous regression, would appreciate if you're able to
> test the new patch (although of course many things in your situation have
> changed now).
> 
> Thanks.
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



[Index of Archives]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux