Skip to content

Commit faf5a97

Browse files
shimodaykwilczynski
authored andcommitted
PCI: rcar-gen4: Add support for R-Car V4H
Add support for r8a779g0 (R-Car V4H). This driver previously supported r8a779f0 (R-Car S4-8). PCIe features of both r8a779f0 and r8a779g0 are almost all the same. For example: - PCI Express Base Specification Revision 4.0 - Root complex mode and endpoint mode are supported However, r8a779g0 requires specific firmware to be provided, to initialize the PHY. Otherwise, the PCIe controller will not work. [kwilczynski: drop the proprietary firmware conversion comment] Link: https://lore.kernel.org/linux-pci/[email protected] Signed-off-by: Yoshihiro Shimoda <[email protected]> Signed-off-by: Krzysztof Wilczyński <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]>
1 parent 2c49151 commit faf5a97

File tree

1 file changed

+197
-1
lines changed

1 file changed

+197
-1
lines changed

drivers/pci/controller/dwc/pcie-rcar-gen4.c

Lines changed: 197 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22
/*
33
* PCIe controller driver for Renesas R-Car Gen4 Series SoCs
44
* Copyright (C) 2022-2023 Renesas Electronics Corporation
5+
*
6+
* The r8a779g0 (R-Car V4H) controller requires a specific firmware to be
7+
* provided, to initialize the PHY. Otherwise, the PCIe controller will not
8+
* work.
59
*/
610

711
#include <linux/delay.h>
12+
#include <linux/firmware.h>
813
#include <linux/interrupt.h>
914
#include <linux/io.h>
15+
#include <linux/iopoll.h>
1016
#include <linux/module.h>
1117
#include <linux/of.h>
1218
#include <linux/pci.h>
@@ -20,9 +26,10 @@
2026
/* Renesas-specific */
2127
/* PCIe Mode Setting Register 0 */
2228
#define PCIEMSR0 0x0000
23-
#define BIFUR_MOD_SET_ON BIT(0)
29+
#define APP_SRIS_MODE BIT(6)
2430
#define DEVICE_TYPE_EP 0
2531
#define DEVICE_TYPE_RC BIT(4)
32+
#define BIFUR_MOD_SET_ON BIT(0)
2633

2734
/* PCIe Interrupt Status 0 */
2835
#define PCIEINTSTS0 0x0084
@@ -37,26 +44,43 @@
3744
#define PCIEDMAINTSTSEN 0x0314
3845
#define PCIEDMAINTSTSEN_INIT GENMASK(15, 0)
3946

47+
/* Port Logic Registers 89 */
48+
#define PRTLGC89 0x0b70
49+
50+
/* Port Logic Registers 90 */
51+
#define PRTLGC90 0x0b74
52+
4053
/* PCIe Reset Control Register 1 */
4154
#define PCIERSTCTRL1 0x0014
4255
#define APP_HOLD_PHY_RST BIT(16)
4356
#define APP_LTSSM_ENABLE BIT(0)
4457

58+
/* PCIe Power Management Control */
59+
#define PCIEPWRMNGCTRL 0x0070
60+
#define APP_CLK_REQ_N BIT(11)
61+
#define APP_CLK_PM_EN BIT(10)
62+
4563
#define RCAR_NUM_SPEED_CHANGE_RETRIES 10
4664
#define RCAR_MAX_LINK_SPEED 4
4765

4866
#define RCAR_GEN4_PCIE_EP_FUNC_DBI_OFFSET 0x1000
4967
#define RCAR_GEN4_PCIE_EP_FUNC_DBI2_OFFSET 0x800
5068

69+
#define RCAR_GEN4_PCIE_FIRMWARE_NAME "rcar_gen4_pcie.bin"
70+
#define RCAR_GEN4_PCIE_FIRMWARE_BASE_ADDR 0xc000
71+
MODULE_FIRMWARE(RCAR_GEN4_PCIE_FIRMWARE_NAME);
72+
5173
struct rcar_gen4_pcie;
5274
struct rcar_gen4_pcie_drvdata {
75+
void (*additional_common_init)(struct rcar_gen4_pcie *rcar);
5376
int (*ltssm_control)(struct rcar_gen4_pcie *rcar, bool enable);
5477
enum dw_pcie_device_mode mode;
5578
};
5679

5780
struct rcar_gen4_pcie {
5881
struct dw_pcie dw;
5982
void __iomem *base;
83+
void __iomem *phy_base;
6084
struct platform_device *pdev;
6185
const struct rcar_gen4_pcie_drvdata *drvdata;
6286
};
@@ -180,6 +204,9 @@ static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar)
180204
if (ret)
181205
goto err_unprepare;
182206

207+
if (rcar->drvdata->additional_common_init)
208+
rcar->drvdata->additional_common_init(rcar);
209+
183210
return 0;
184211

185212
err_unprepare:
@@ -221,6 +248,10 @@ static void rcar_gen4_pcie_unprepare(struct rcar_gen4_pcie *rcar)
221248

222249
static int rcar_gen4_pcie_get_resources(struct rcar_gen4_pcie *rcar)
223250
{
251+
rcar->phy_base = devm_platform_ioremap_resource_byname(rcar->pdev, "phy");
252+
if (IS_ERR(rcar->phy_base))
253+
return PTR_ERR(rcar->phy_base);
254+
224255
/* Renesas-specific registers */
225256
rcar->base = devm_platform_ioremap_resource_byname(rcar->pdev, "app");
226257

@@ -528,6 +559,167 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
528559
return 0;
529560
}
530561

562+
static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
563+
{
564+
struct dw_pcie *dw = &rcar->dw;
565+
u32 val;
566+
567+
val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
568+
val &= ~PORT_LANE_SKEW_INSERT_MASK;
569+
if (dw->num_lanes < 4)
570+
val |= BIT(6);
571+
dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
572+
573+
val = readl(rcar->base + PCIEPWRMNGCTRL);
574+
val |= APP_CLK_REQ_N | APP_CLK_PM_EN;
575+
writel(val, rcar->base + PCIEPWRMNGCTRL);
576+
}
577+
578+
static void rcar_gen4_pcie_phy_reg_update_bits(struct rcar_gen4_pcie *rcar,
579+
u32 offset, u32 mask, u32 val)
580+
{
581+
u32 tmp;
582+
583+
tmp = readl(rcar->phy_base + offset);
584+
tmp &= ~mask;
585+
tmp |= val;
586+
writel(tmp, rcar->phy_base + offset);
587+
}
588+
589+
/*
590+
* SoC datasheet suggests checking port logic register bits during firmware
591+
* write. If read returns non-zero value, then this function returns -EAGAIN
592+
* indicating that the write needs to be done again. If read returns zero,
593+
* then return 0 to indicate success.
594+
*/
595+
static int rcar_gen4_pcie_reg_test_bit(struct rcar_gen4_pcie *rcar,
596+
u32 offset, u32 mask)
597+
{
598+
struct dw_pcie *dw = &rcar->dw;
599+
600+
if (dw_pcie_readl_dbi(dw, offset) & mask)
601+
return -EAGAIN;
602+
603+
return 0;
604+
}
605+
606+
static int rcar_gen4_pcie_download_phy_firmware(struct rcar_gen4_pcie *rcar)
607+
{
608+
/* The check_addr values are magical numbers in the datasheet */
609+
const u32 check_addr[] = { 0x00101018, 0x00101118, 0x00101021, 0x00101121};
610+
struct dw_pcie *dw = &rcar->dw;
611+
const struct firmware *fw;
612+
unsigned int i, timeout;
613+
u32 data;
614+
int ret;
615+
616+
ret = request_firmware(&fw, RCAR_GEN4_PCIE_FIRMWARE_NAME, dw->dev);
617+
if (ret) {
618+
dev_err(dw->dev, "Failed to load firmware (%s): %d\n",
619+
RCAR_GEN4_PCIE_FIRMWARE_NAME, ret);
620+
return ret;
621+
}
622+
623+
for (i = 0; i < (fw->size / 2); i++) {
624+
data = fw->data[(i * 2) + 1] << 8 | fw->data[i * 2];
625+
timeout = 100;
626+
do {
627+
dw_pcie_writel_dbi(dw, PRTLGC89, RCAR_GEN4_PCIE_FIRMWARE_BASE_ADDR + i);
628+
dw_pcie_writel_dbi(dw, PRTLGC90, data);
629+
if (!rcar_gen4_pcie_reg_test_bit(rcar, PRTLGC89, BIT(30)))
630+
break;
631+
if (!(--timeout)) {
632+
ret = -ETIMEDOUT;
633+
goto exit;
634+
}
635+
usleep_range(100, 200);
636+
} while (1);
637+
}
638+
639+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x0f8, BIT(17), BIT(17));
640+
641+
for (i = 0; i < ARRAY_SIZE(check_addr); i++) {
642+
timeout = 100;
643+
do {
644+
dw_pcie_writel_dbi(dw, PRTLGC89, check_addr[i]);
645+
ret = rcar_gen4_pcie_reg_test_bit(rcar, PRTLGC89, BIT(30));
646+
ret |= rcar_gen4_pcie_reg_test_bit(rcar, PRTLGC90, BIT(0));
647+
if (!ret)
648+
break;
649+
if (!(--timeout)) {
650+
ret = -ETIMEDOUT;
651+
goto exit;
652+
}
653+
usleep_range(100, 200);
654+
} while (1);
655+
}
656+
657+
exit:
658+
release_firmware(fw);
659+
660+
return ret;
661+
}
662+
663+
static int rcar_gen4_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
664+
{
665+
struct dw_pcie *dw = &rcar->dw;
666+
u32 val;
667+
int ret;
668+
669+
if (!enable) {
670+
val = readl(rcar->base + PCIERSTCTRL1);
671+
val &= ~APP_LTSSM_ENABLE;
672+
writel(val, rcar->base + PCIERSTCTRL1);
673+
674+
return 0;
675+
}
676+
677+
val = dw_pcie_readl_dbi(dw, PCIE_PORT_FORCE);
678+
val |= PORT_FORCE_DO_DESKEW_FOR_SRIS;
679+
dw_pcie_writel_dbi(dw, PCIE_PORT_FORCE, val);
680+
681+
val = readl(rcar->base + PCIEMSR0);
682+
val |= APP_SRIS_MODE;
683+
writel(val, rcar->base + PCIEMSR0);
684+
685+
/*
686+
* The R-Car Gen4 datasheet doesn't describe the PHY registers' name.
687+
* But, the initialization procedure describes these offsets. So,
688+
* this driver has magical offset numbers.
689+
*/
690+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x700, BIT(28), 0);
691+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x700, BIT(20), 0);
692+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x700, BIT(12), 0);
693+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x700, BIT(4), 0);
694+
695+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x148, GENMASK(23, 22), BIT(22));
696+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x148, GENMASK(18, 16), GENMASK(17, 16));
697+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x148, GENMASK(7, 6), BIT(6));
698+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x148, GENMASK(2, 0), GENMASK(11, 0));
699+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x1d4, GENMASK(16, 15), GENMASK(16, 15));
700+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x514, BIT(26), BIT(26));
701+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x0f8, BIT(16), 0);
702+
rcar_gen4_pcie_phy_reg_update_bits(rcar, 0x0f8, BIT(19), BIT(19));
703+
704+
val = readl(rcar->base + PCIERSTCTRL1);
705+
val &= ~APP_HOLD_PHY_RST;
706+
writel(val, rcar->base + PCIERSTCTRL1);
707+
708+
ret = readl_poll_timeout(rcar->phy_base + 0x0f8, val, !(val & BIT(18)), 100, 10000);
709+
if (ret < 0)
710+
return ret;
711+
712+
ret = rcar_gen4_pcie_download_phy_firmware(rcar);
713+
if (ret)
714+
return ret;
715+
716+
val = readl(rcar->base + PCIERSTCTRL1);
717+
val |= APP_LTSSM_ENABLE;
718+
writel(val, rcar->base + PCIERSTCTRL1);
719+
720+
return 0;
721+
}
722+
531723
static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie = {
532724
.ltssm_control = r8a779f0_pcie_ltssm_control,
533725
.mode = DW_PCIE_RC_TYPE,
@@ -539,10 +731,14 @@ static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie_ep = {
539731
};
540732

541733
static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie = {
734+
.additional_common_init = rcar_gen4_pcie_additional_common_init,
735+
.ltssm_control = rcar_gen4_pcie_ltssm_control,
542736
.mode = DW_PCIE_RC_TYPE,
543737
};
544738

545739
static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie_ep = {
740+
.additional_common_init = rcar_gen4_pcie_additional_common_init,
741+
.ltssm_control = rcar_gen4_pcie_ltssm_control,
546742
.mode = DW_PCIE_EP_TYPE,
547743
};
548744

0 commit comments

Comments
 (0)