Message ID | 20240806075843.277969-3-Shyam-sundar.S-k@amd.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Introduce initial AMD I3C HCI driver support | expand |
On 8/6/2024 13:28, Shyam Sundar S K wrote: > The AMD HCI controller currently only supports PIO mode but exposes DMA > rings to the OS, which leads to the controller being configured in DMA > mode. To address this, add a quirk to avoid configuring the controller in > DMA mode and default to PIO mode. > > Additionally, introduce a generic quirk infrastructure to the mipi-i3c-hci > driver to facilitate seamless future quirk additions. > > Co-developed-by: Krishnamoorthi M <krishnamoorthi.m@amd.com> > Signed-off-by: Krishnamoorthi M <krishnamoorthi.m@amd.com> > Co-developed-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com> > Signed-off-by: Guruvendra Punugupati <Guruvendra.Punugupati@amd.com> > Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> > --- > drivers/i3c/master/mipi-i3c-hci/Makefile | 3 ++- > drivers/i3c/master/mipi-i3c-hci/core.c | 15 ++++++++++++++- > drivers/i3c/master/mipi-i3c-hci/hci.h | 3 +++ > drivers/i3c/master/mipi-i3c-hci/hci_quirks.c | 20 ++++++++++++++++++++ > 4 files changed, 39 insertions(+), 2 deletions(-) > create mode 100644 drivers/i3c/master/mipi-i3c-hci/hci_quirks.c > > diff --git a/drivers/i3c/master/mipi-i3c-hci/Makefile b/drivers/i3c/master/mipi-i3c-hci/Makefile > index a658e7b8262c..1f8cd5c48fde 100644 > --- a/drivers/i3c/master/mipi-i3c-hci/Makefile > +++ b/drivers/i3c/master/mipi-i3c-hci/Makefile > @@ -3,4 +3,5 @@ > obj-$(CONFIG_MIPI_I3C_HCI) += mipi-i3c-hci.o > mipi-i3c-hci-y := core.o ext_caps.o pio.o dma.o \ > cmd_v1.o cmd_v2.o \ > - dat_v1.o dct_v1.o > + dat_v1.o dct_v1.o \ > + hci_quirks.o > diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c > index 5ef848833a81..7843a3ac2121 100644 > --- a/drivers/i3c/master/mipi-i3c-hci/core.c > +++ b/drivers/i3c/master/mipi-i3c-hci/core.c > @@ -33,6 +33,7 @@ > #define reg_clear(r, v) reg_write(r, reg_read(r) & ~(v)) > > #define HCI_VERSION 0x00 /* HCI Version (in BCD) */ > +#define HCI_VERSION_V1 0x100 /* MIPI HCI Version number V1.0 */ > > #define HC_CONTROL 0x04 > #define HC_CONTROL_BUS_ENABLE BIT(31) > @@ -753,6 +754,14 @@ static int i3c_hci_init(struct i3c_hci *hci) > return -EINVAL; > } > > + /* Initialize quirks for AMD platforms */ > + amd_i3c_hci_quirks_init(hci); > + > + regval = reg_read(HCI_VERSION); > + > + if (hci->quirks & HCI_QUIRK_PIO_MODE) > + hci->RHS_regs = NULL; > + > /* Try activating DMA operations first */ > if (hci->RHS_regs) { > reg_clear(HC_CONTROL, HC_CONTROL_PIO_MODE); > @@ -768,7 +777,11 @@ static int i3c_hci_init(struct i3c_hci *hci) > /* If no DMA, try PIO */ > if (!hci->io && hci->PIO_regs) { > reg_set(HC_CONTROL, HC_CONTROL_PIO_MODE); > - if (!(reg_read(HC_CONTROL) & HC_CONTROL_PIO_MODE)) { > + /* > + * HC_CONTROL_PIO_MODE bit not present in HC_CONTROL register w.r.t V1.0 > + * specification. So skip checking PIO_MODE bit status > + */ > + if (regval > HCI_VERSION_V1 && !(reg_read(HC_CONTROL) & HC_CONTROL_PIO_MODE)) { Jarkko, Apologies. I missed to address your comment on splitting the version check and quirk stuff separately. Will do a resend, kindly ignore this version. Thanks, Shyam > dev_err(&hci->master.dev, "DMA mode is stuck\n"); > ret = -EIO; > } else { > diff --git a/drivers/i3c/master/mipi-i3c-hci/hci.h b/drivers/i3c/master/mipi-i3c-hci/hci.h > index f94d95e024be..91e8a3833f3d 100644 > --- a/drivers/i3c/master/mipi-i3c-hci/hci.h > +++ b/drivers/i3c/master/mipi-i3c-hci/hci.h > @@ -135,6 +135,7 @@ struct i3c_hci_dev_data { > > /* list of quirks */ > #define HCI_QUIRK_RAW_CCC BIT(1) /* CCC framing must be explicit */ > +#define HCI_QUIRK_PIO_MODE BIT(2) /* Set PIO mode for AMD platforms */ > > > /* global functions */ > @@ -142,4 +143,6 @@ void mipi_i3c_hci_resume(struct i3c_hci *hci); > void mipi_i3c_hci_pio_reset(struct i3c_hci *hci); > void mipi_i3c_hci_dct_index_reset(struct i3c_hci *hci); > > +void amd_i3c_hci_quirks_init(struct i3c_hci *hci); > + > #endif > diff --git a/drivers/i3c/master/mipi-i3c-hci/hci_quirks.c b/drivers/i3c/master/mipi-i3c-hci/hci_quirks.c > new file mode 100644 > index 000000000000..8a8fbd697175 > --- /dev/null > +++ b/drivers/i3c/master/mipi-i3c-hci/hci_quirks.c > @@ -0,0 +1,20 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * I3C HCI Quirks > + * > + * Copyright 2024 Advanced Micro Devices, Inc. > + * > + * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> > + * Guruvendra Punugupati <Guruvendra.Punugupati@amd.com> > + */ > + > +#include <linux/i3c/master.h> > +#include "hci.h" > + > +void amd_i3c_hci_quirks_init(struct i3c_hci *hci) > +{ > +#if defined(CONFIG_X86) > + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) > + hci->quirks |= HCI_QUIRK_PIO_MODE; > +#endif > +}
diff --git a/drivers/i3c/master/mipi-i3c-hci/Makefile b/drivers/i3c/master/mipi-i3c-hci/Makefile index a658e7b8262c..1f8cd5c48fde 100644 --- a/drivers/i3c/master/mipi-i3c-hci/Makefile +++ b/drivers/i3c/master/mipi-i3c-hci/Makefile @@ -3,4 +3,5 @@ obj-$(CONFIG_MIPI_I3C_HCI) += mipi-i3c-hci.o mipi-i3c-hci-y := core.o ext_caps.o pio.o dma.o \ cmd_v1.o cmd_v2.o \ - dat_v1.o dct_v1.o + dat_v1.o dct_v1.o \ + hci_quirks.o diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c index 5ef848833a81..7843a3ac2121 100644 --- a/drivers/i3c/master/mipi-i3c-hci/core.c +++ b/drivers/i3c/master/mipi-i3c-hci/core.c @@ -33,6 +33,7 @@ #define reg_clear(r, v) reg_write(r, reg_read(r) & ~(v)) #define HCI_VERSION 0x00 /* HCI Version (in BCD) */ +#define HCI_VERSION_V1 0x100 /* MIPI HCI Version number V1.0 */ #define HC_CONTROL 0x04 #define HC_CONTROL_BUS_ENABLE BIT(31) @@ -753,6 +754,14 @@ static int i3c_hci_init(struct i3c_hci *hci) return -EINVAL; } + /* Initialize quirks for AMD platforms */ + amd_i3c_hci_quirks_init(hci); + + regval = reg_read(HCI_VERSION); + + if (hci->quirks & HCI_QUIRK_PIO_MODE) + hci->RHS_regs = NULL; + /* Try activating DMA operations first */ if (hci->RHS_regs) { reg_clear(HC_CONTROL, HC_CONTROL_PIO_MODE); @@ -768,7 +777,11 @@ static int i3c_hci_init(struct i3c_hci *hci) /* If no DMA, try PIO */ if (!hci->io && hci->PIO_regs) { reg_set(HC_CONTROL, HC_CONTROL_PIO_MODE); - if (!(reg_read(HC_CONTROL) & HC_CONTROL_PIO_MODE)) { + /* + * HC_CONTROL_PIO_MODE bit not present in HC_CONTROL register w.r.t V1.0 + * specification. So skip checking PIO_MODE bit status + */ + if (regval > HCI_VERSION_V1 && !(reg_read(HC_CONTROL) & HC_CONTROL_PIO_MODE)) { dev_err(&hci->master.dev, "DMA mode is stuck\n"); ret = -EIO; } else { diff --git a/drivers/i3c/master/mipi-i3c-hci/hci.h b/drivers/i3c/master/mipi-i3c-hci/hci.h index f94d95e024be..91e8a3833f3d 100644 --- a/drivers/i3c/master/mipi-i3c-hci/hci.h +++ b/drivers/i3c/master/mipi-i3c-hci/hci.h @@ -135,6 +135,7 @@ struct i3c_hci_dev_data { /* list of quirks */ #define HCI_QUIRK_RAW_CCC BIT(1) /* CCC framing must be explicit */ +#define HCI_QUIRK_PIO_MODE BIT(2) /* Set PIO mode for AMD platforms */ /* global functions */ @@ -142,4 +143,6 @@ void mipi_i3c_hci_resume(struct i3c_hci *hci); void mipi_i3c_hci_pio_reset(struct i3c_hci *hci); void mipi_i3c_hci_dct_index_reset(struct i3c_hci *hci); +void amd_i3c_hci_quirks_init(struct i3c_hci *hci); + #endif diff --git a/drivers/i3c/master/mipi-i3c-hci/hci_quirks.c b/drivers/i3c/master/mipi-i3c-hci/hci_quirks.c new file mode 100644 index 000000000000..8a8fbd697175 --- /dev/null +++ b/drivers/i3c/master/mipi-i3c-hci/hci_quirks.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * I3C HCI Quirks + * + * Copyright 2024 Advanced Micro Devices, Inc. + * + * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> + * Guruvendra Punugupati <Guruvendra.Punugupati@amd.com> + */ + +#include <linux/i3c/master.h> +#include "hci.h" + +void amd_i3c_hci_quirks_init(struct i3c_hci *hci) +{ +#if defined(CONFIG_X86) + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) + hci->quirks |= HCI_QUIRK_PIO_MODE; +#endif +}