diff --git a/arch/arm/configs/rk3506_defconfig b/arch/arm/configs/rk3506_defconfig index 041bdd3e38c8..8af6cc241401 100644 --- a/arch/arm/configs/rk3506_defconfig +++ b/arch/arm/configs/rk3506_defconfig @@ -282,13 +282,14 @@ CONFIG_DMABUF_HEAPS_CMA=y # CONFIG_VIRTIO_MENU is not set # CONFIG_VHOST_MENU is not set CONFIG_STAGING=y +# CONFIG_ROCKCHIP_CLK_INV is not set CONFIG_ROCKCHIP_CLK_OUT=y +# CONFIG_ROCKCHIP_CLK_PVTM is not set # CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set # CONFIG_IOMMU_SUPPORT is not set CONFIG_CPU_RK3506=y CONFIG_ROCKCHIP_CPUINFO=y CONFIG_ROCKCHIP_OPP=y -CONFIG_ROCKCHIP_PVTM=y CONFIG_ROCKCHIP_SUSPEND_MODE=y CONFIG_ROCKCHIP_SYSTEM_MONITOR=y CONFIG_FIQ_DEBUGGER=y diff --git a/drivers/media/platform/rockchip/flexbus_cif/common.c b/drivers/media/platform/rockchip/flexbus_cif/common.c index 282c5b49393e..ab153d1ff6fb 100644 --- a/drivers/media/platform/rockchip/flexbus_cif/common.c +++ b/drivers/media/platform/rockchip/flexbus_cif/common.c @@ -11,6 +11,8 @@ #include "dev.h" #include "common.h" +MODULE_IMPORT_NS(DMA_BUF); + static void flexbus_cif_init_dummy_vb2(struct flexbus_cif_device *dev, struct flexbus_cif_dummy_buffer *buf) { diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index c01dfedd7dd4..e2e05744a251 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -135,6 +135,9 @@ struct rk_pcie { bool slot_pluggable; struct gpio_hotplug_slot hp_slot; bool hp_no_link; + bool is_lpbk; + bool is_comp; + bool have_rasdes; struct regulator *vpcie3v3; struct irq_domain *irq_domain; raw_spinlock_t intx_lock; @@ -153,8 +156,6 @@ struct rk_pcie_of_data { }; #define to_rk_pcie(x) dev_get_drvdata((x)->dev) -static int rk_pcie_disable_power(struct rk_pcie *rk_pcie); -static int rk_pcie_enable_power(struct rk_pcie *rk_pcie); static inline u32 rk_pcie_readl_apb(struct rk_pcie *rk_pcie, u32 reg) { @@ -201,7 +202,7 @@ static void disable_aspm_l1ss(struct rk_pcie *rk_pcie) static inline void disable_aspm_l1ss(struct rk_pcie *rk_pcie) { return; } #endif -static inline void rk_pcie_set_mode(struct rk_pcie *rk_pcie) +static inline void rk_pcie_set_rc_mode(struct rk_pcie *rk_pcie) { if (rk_pcie->supports_clkreq) { /* Application is ready to have reference clock removed */ @@ -272,6 +273,36 @@ static void rk_pcie_debug_dump(struct rk_pcie *rk_pcie) #endif } +static int rk_pcie_enable_power(struct rk_pcie *rk_pcie) +{ + int ret = 0; + struct device *dev = rk_pcie->pci->dev; + + if (IS_ERR(rk_pcie->vpcie3v3)) + return ret; + + ret = regulator_enable(rk_pcie->vpcie3v3); + if (ret) + dev_err(dev, "fail to enable vpcie3v3 regulator\n"); + + return ret; +} + +static int rk_pcie_disable_power(struct rk_pcie *rk_pcie) +{ + int ret = 0; + struct device *dev = rk_pcie->pci->dev; + + if (IS_ERR(rk_pcie->vpcie3v3)) + return ret; + + ret = regulator_disable(rk_pcie->vpcie3v3); + if (ret) + dev_err(dev, "fail to disable vpcie3v3 regulator\n"); + + return ret; +} + static int rk_pcie_establish_link(struct dw_pcie *pci) { int retries, power; @@ -392,182 +423,6 @@ static bool rk_pcie_udma_enabled(struct rk_pcie *rk_pcie) PCIE_DMA_CTRL_OFF); } -static int rk_pcie_init_dma_trx(struct rk_pcie *rk_pcie) -{ - if (!rk_pcie_udma_enabled(rk_pcie)) - return 0; - - rk_pcie->dma_obj = pcie_dw_dmatest_register(rk_pcie->pci->dev, true); - if (IS_ERR(rk_pcie->dma_obj)) { - dev_err(rk_pcie->pci->dev, "failed to prepare dmatest\n"); - return -EINVAL; - } - - /* Enable client write and read interrupt */ - rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0xc000000); - - /* Enable core write interrupt */ - dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK, - 0x0); - /* Enable core read interrupt */ - dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK, - 0x0); - return 0; -} - -#ifdef MODULE -void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val) -{ - int ret; - - if (pci->ops && pci->ops->write_dbi2) { - pci->ops->write_dbi2(pci, pci->dbi_base2, reg, size, val); - return; - } - - ret = dw_pcie_write(pci->dbi_base2 + reg, size, val); - if (ret) - dev_err(pci->dev, "write DBI address failed\n"); -} -#endif - -static struct dw_pcie_host_ops rk_pcie_host_ops; - -static int rk_add_pcie_port(struct rk_pcie *rk_pcie, struct platform_device *pdev) -{ - int ret; - struct dw_pcie *pci = rk_pcie->pci; - struct dw_pcie_rp *pp = &pci->pp; - struct device *dev = pci->dev; - - pp->ops = &rk_pcie_host_ops; - - if (IS_ENABLED(CONFIG_PCI_MSI)) { - if (rk_pcie->msi_vector_num > 0) { - dev_info(dev, "max MSI vector is %d\n", rk_pcie->msi_vector_num); - pp->num_vectors = rk_pcie->msi_vector_num; - } - } - - ret = dw_pcie_host_init(pp); - if (ret) { - dev_err(dev, "failed to initialize host\n"); - return ret; - } - - /* Disable BAR0 BAR1 */ - dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_0, 0x0); - dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_1, 0x0); - - return 0; -} - -static int rk_pcie_clk_init(struct rk_pcie *rk_pcie) -{ - struct device *dev = rk_pcie->pci->dev; - int ret; - - rk_pcie->clk_cnt = devm_clk_bulk_get_all(dev, &rk_pcie->clks); - if (rk_pcie->clk_cnt < 1) - return -ENODEV; - - ret = clk_bulk_prepare_enable(rk_pcie->clk_cnt, rk_pcie->clks); - if (ret) { - dev_err(dev, "failed to prepare enable pcie bulk clks: %d\n", ret); - return ret; - } - - return 0; -} - -static int rk_pcie_resource_get(struct platform_device *pdev, - struct rk_pcie *rk_pcie) -{ - struct resource *dbi_base; - struct resource *apb_base; - - dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "pcie-dbi"); - if (!dbi_base) { - dev_err(&pdev->dev, "get pcie-dbi failed\n"); - return -ENODEV; - } - - rk_pcie->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); - if (IS_ERR(rk_pcie->dbi_base)) - return PTR_ERR(rk_pcie->dbi_base); - - rk_pcie->pci->dbi_base = rk_pcie->dbi_base; - rk_pcie->pci->dbi_base2 = rk_pcie->pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET; - - apb_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "pcie-apb"); - if (!apb_base) { - dev_err(&pdev->dev, "get pcie-apb failed\n"); - return -ENODEV; - } - rk_pcie->apb_base = devm_ioremap_resource(&pdev->dev, apb_base); - if (IS_ERR(rk_pcie->apb_base)) - return PTR_ERR(rk_pcie->apb_base); - - /* - * Rest the device before enabling power because some of the - * platforms may use external refclk input with the some power - * rail connect to 100MHz OSC chip. So once the power is up for - * the slot and the refclk is available, which isn't quite follow - * the spec. We should make sure it is in reset state before - * everthing's ready. - */ - rk_pcie->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", - GPIOD_OUT_LOW); - if (IS_ERR(rk_pcie->rst_gpio)) { - dev_err(&pdev->dev, "invalid reset-gpios property in node\n"); - return PTR_ERR(rk_pcie->rst_gpio); - } - - if (device_property_read_u32(&pdev->dev, "rockchip,perst-inactive-ms", - &rk_pcie->perst_inactive_ms)) - rk_pcie->perst_inactive_ms = 200; - - rk_pcie->prsnt_gpio = devm_gpiod_get_optional(&pdev->dev, "prsnt", GPIOD_IN); - if (IS_ERR_OR_NULL(rk_pcie->prsnt_gpio)) - dev_info(&pdev->dev, "invalid prsnt-gpios property in node\n"); - - return 0; -} - -static int rk_pcie_phy_init(struct rk_pcie *rk_pcie) -{ - int ret; - struct device *dev = rk_pcie->pci->dev; - - rk_pcie->phy = devm_phy_optional_get(dev, "pcie-phy"); - if (IS_ERR(rk_pcie->phy)) { - if (PTR_ERR(rk_pcie->phy) != -EPROBE_DEFER) - dev_info(dev, "missing phy\n"); - return PTR_ERR(rk_pcie->phy); - } - - ret = phy_set_mode_ext(rk_pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC); - if (ret) { - dev_err(dev, "fail to set phy to rc mode, err %d\n", ret); - return ret; - } - - if (rk_pcie->bifurcation) - phy_set_mode_ext(rk_pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_BIFURCATION); - - ret = phy_init(rk_pcie->phy); - if (ret < 0) { - dev_err(dev, "fail to init phy, err %d\n", ret); - return ret; - } - - phy_power_on(rk_pcie->phy); - - return 0; -} - static void rk_pcie_start_dma_rd(struct dma_trx_obj *obj, struct dma_table *cur, int ctr_off) { struct rk_pcie *rk_pcie = dev_get_drvdata(obj->dev); @@ -655,6 +510,237 @@ static void rk_pcie_config_dma_dwc(struct dma_table *table) table->start.chnl = table->chn; } +static int rk_pcie_init_dma_trx(struct rk_pcie *rk_pcie) +{ + if (!rk_pcie_udma_enabled(rk_pcie)) + return 0; + + rk_pcie->dma_obj = pcie_dw_dmatest_register(rk_pcie->pci->dev, true); + if (IS_ERR(rk_pcie->dma_obj)) { + dev_err(rk_pcie->pci->dev, "failed to prepare dmatest\n"); + return -EINVAL; + } + + /* Enable client write and read interrupt */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0xc000000); + + /* Enable core write interrupt */ + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK, + 0x0); + /* Enable core read interrupt */ + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK, + 0x0); + + rk_pcie->dma_obj->start_dma_func = rk_pcie_start_dma_dwc; + rk_pcie->dma_obj->config_dma_func = rk_pcie_config_dma_dwc; + + return 0; +} + +#ifdef MODULE +void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val) +{ + int ret; + + if (pci->ops && pci->ops->write_dbi2) { + pci->ops->write_dbi2(pci, pci->dbi_base2, reg, size, val); + return; + } + + ret = dw_pcie_write(pci->dbi_base2 + reg, size, val); + if (ret) + dev_err(pci->dev, "write DBI address failed\n"); +} +#endif + +static struct dw_pcie_host_ops rk_pcie_host_ops; + +static int rk_add_pcie_port(struct rk_pcie *rk_pcie, struct platform_device *pdev) +{ + int ret; + struct dw_pcie *pci = rk_pcie->pci; + struct dw_pcie_rp *pp = &pci->pp; + struct device *dev = pci->dev; + + pp->ops = &rk_pcie_host_ops; + + if (IS_ENABLED(CONFIG_PCI_MSI)) { + if (rk_pcie->msi_vector_num > 0) { + dev_info(dev, "max MSI vector is %d\n", rk_pcie->msi_vector_num); + pp->num_vectors = rk_pcie->msi_vector_num; + } + } + + ret = dw_pcie_host_init(pp); + if (ret) { + dev_err(dev, "failed to initialize host\n"); + return ret; + } + + /* Disable BAR0 BAR1 */ + dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_0, 0x0); + dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_1, 0x0); + + return 0; +} + +static int rk_pcie_resource_get(struct platform_device *pdev, + struct rk_pcie *rk_pcie) +{ + struct resource *dbi_base; + struct resource *apb_base; + u32 val = 0; + + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "pcie-dbi"); + if (!dbi_base) { + dev_err(&pdev->dev, "get pcie-dbi failed\n"); + return -ENODEV; + } + + rk_pcie->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); + if (IS_ERR(rk_pcie->dbi_base)) + return PTR_ERR(rk_pcie->dbi_base); + + rk_pcie->pci->dbi_base = rk_pcie->dbi_base; + rk_pcie->pci->dbi_base2 = rk_pcie->pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET; + + apb_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "pcie-apb"); + if (!apb_base) { + dev_err(&pdev->dev, "get pcie-apb failed\n"); + return -ENODEV; + } + rk_pcie->apb_base = devm_ioremap_resource(&pdev->dev, apb_base); + if (IS_ERR(rk_pcie->apb_base)) + return PTR_ERR(rk_pcie->apb_base); + + /* + * Rest the device before enabling power because some of the + * platforms may use external refclk input with the some power + * rail connect to 100MHz OSC chip. So once the power is up for + * the slot and the refclk is available, which isn't quite follow + * the spec. We should make sure it is in reset state before + * everthing's ready. + */ + rk_pcie->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(rk_pcie->rst_gpio)) { + dev_err(&pdev->dev, "invalid reset-gpios property in node\n"); + return PTR_ERR(rk_pcie->rst_gpio); + } + + if (device_property_read_u32(&pdev->dev, "rockchip,perst-inactive-ms", + &rk_pcie->perst_inactive_ms)) + rk_pcie->perst_inactive_ms = 200; + + rk_pcie->prsnt_gpio = devm_gpiod_get_optional(&pdev->dev, "prsnt", GPIOD_IN); + if (IS_ERR_OR_NULL(rk_pcie->prsnt_gpio)) + dev_info(&pdev->dev, "invalid prsnt-gpios property in node\n"); + + rk_pcie->clk_cnt = devm_clk_bulk_get_all(&pdev->dev, &rk_pcie->clks); + if (rk_pcie->clk_cnt < 1) + return -ENODEV; + + rk_pcie->rsts = devm_reset_control_array_get_exclusive(&pdev->dev); + if (IS_ERR(rk_pcie->rsts)) { + dev_err(&pdev->dev, "failed to get reset lines\n"); + return PTR_ERR(rk_pcie->rsts); + } + + if (device_property_read_bool(&pdev->dev, "rockchip,bifurcation")) + rk_pcie->bifurcation = true; + + rk_pcie->supports_clkreq = device_property_read_bool(&pdev->dev, "supports-clkreq"); + + if (device_property_read_bool(&pdev->dev, "hotplug-gpios") || + device_property_read_bool(&pdev->dev, "hotplug-gpio")) { + rk_pcie->slot_pluggable = true; + dev_info(&pdev->dev, "support hotplug-gpios!\n"); + } + + /* Skip waiting for training to pass in system PM routine */ + if (device_property_read_bool(&pdev->dev, "rockchip,skip-scan-in-resume")) + rk_pcie->skip_scan_in_resume = true; + + /* Force into loopback master mode */ + if (device_property_read_bool(&pdev->dev, "rockchip,lpbk-master")) { + rk_pcie->is_lpbk = true; + rk_pcie->is_signal_test = true; + } + + /* + * Force into compliance mode + * comp_prst is a two dimensional array of which the first element + * stands for speed mode, and the second one is preset value encoding: + * [0] 0->SMA tool control the signal switch, 1/2/3 is for manual Gen setting + * [1] transmitter setting for manual Gen setting, valid only if [0] isn't zero. + */ + if (!device_property_read_u32_array(&pdev->dev, "rockchip,compliance-mode", + rk_pcie->comp_prst, 2)) { + WARN_ON_ONCE(rk_pcie->comp_prst[0] > 3 || rk_pcie->comp_prst[1] > 10); + if (!rk_pcie->comp_prst[0]) + dev_info(&pdev->dev, "Auto compliance mode for SMA tool.\n"); + else + dev_info(&pdev->dev, "compliance mode for soldered board Gen%d, P%d.\n", + rk_pcie->comp_prst[0], rk_pcie->comp_prst[1]); + + rk_pcie->is_comp = true; + rk_pcie->is_signal_test = true; + } + +retry_regulator: + rk_pcie->vpcie3v3 = devm_regulator_get_optional(&pdev->dev, "vpcie3v3"); + if (IS_ERR(rk_pcie->vpcie3v3)) { + if (PTR_ERR(rk_pcie->vpcie3v3) != -ENODEV) { + if (IS_ENABLED(CONFIG_PCIE_RK_THREADED_INIT)) { + /* Deferred but in threaded context for most 10s */ + msleep(20); + if (++val < 500) + goto retry_regulator; + } + + return PTR_ERR(rk_pcie->vpcie3v3); + } + + dev_info(&pdev->dev, "no vpcie3v3 regulator found\n"); + } + + return 0; +} + +static int rk_pcie_phy_init(struct rk_pcie *rk_pcie) +{ + int ret; + struct device *dev = rk_pcie->pci->dev; + + rk_pcie->phy = devm_phy_optional_get(dev, "pcie-phy"); + if (IS_ERR(rk_pcie->phy)) { + if (PTR_ERR(rk_pcie->phy) != -EPROBE_DEFER) + dev_info(dev, "missing phy\n"); + return PTR_ERR(rk_pcie->phy); + } + + ret = phy_set_mode_ext(rk_pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC); + if (ret) { + dev_err(dev, "fail to set phy to rc mode, err %d\n", ret); + return ret; + } + + if (rk_pcie->bifurcation) + phy_set_mode_ext(rk_pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_BIFURCATION); + + ret = phy_init(rk_pcie->phy); + if (ret < 0) { + dev_err(dev, "fail to init phy, err %d\n", ret); + return ret; + } + + phy_power_on(rk_pcie->phy); + + return 0; +} + static void rk_pcie_hot_rst_work(struct work_struct *work) { struct rk_pcie *rk_pcie = container_of(work, struct rk_pcie, hot_rst_work); @@ -893,36 +979,6 @@ static int rk_pcie_init_irq_domain(struct rk_pcie *rockchip) return 0; } -static int rk_pcie_enable_power(struct rk_pcie *rk_pcie) -{ - int ret = 0; - struct device *dev = rk_pcie->pci->dev; - - if (IS_ERR(rk_pcie->vpcie3v3)) - return ret; - - ret = regulator_enable(rk_pcie->vpcie3v3); - if (ret) - dev_err(dev, "fail to enable vpcie3v3 regulator\n"); - - return ret; -} - -static int rk_pcie_disable_power(struct rk_pcie *rk_pcie) -{ - int ret = 0; - struct device *dev = rk_pcie->pci->dev; - - if (IS_ERR(rk_pcie->vpcie3v3)) - return ret; - - ret = regulator_disable(rk_pcie->vpcie3v3); - if (ret) - dev_err(dev, "fail to disable vpcie3v3 regulator\n"); - - return ret; -} - #define RAS_DES_EVENT(ss, v) \ do { \ dw_pcie_writel_dbi(pcie->pci, cap_base + 8, v); \ @@ -1061,6 +1117,9 @@ static int rockchip_pcie_debugfs_init(struct rk_pcie *pcie) { struct dentry *file; + if (!IS_ENABLED(CONFIG_DEBUG_FS) || !pcie->have_rasdes) + return 0; + pcie->debugfs = debugfs_create_dir(dev_name(pcie->pci->dev), NULL); if (!pcie->debugfs) return -ENOMEM; @@ -1115,6 +1174,50 @@ static const struct gpio_hotplug_slot_plat_ops rk_pcie_gpio_hp_plat_ops = { .disable = rk_pcie_slot_disable, }; +static int rk_pcie_init_irq_and_wq(struct rk_pcie *rk_pcie, struct platform_device *pdev) +{ + struct device *dev = rk_pcie->pci->dev; + int ret, irq; + + /* + * Misc interrupts was masked by default. However, they will be + * unmasked by FW before jumpping into kernel. Mask all misc interrupts, + * as we don't need to ack them before registering irq. And they will be + * unmasked later. + */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0xffffffff); + + ret = rk_pcie_request_sys_irq(rk_pcie, pdev); + if (ret) { + dev_err(dev, "pcie irq init failed\n"); + return ret; + } + + /* Legacy interrupt is optional */ + ret = rk_pcie_init_irq_domain(rk_pcie); + if (!ret) { + irq = platform_get_irq_byname(pdev, "legacy"); + if (irq >= 0) { + irq_set_chained_handler_and_data(irq, rk_pcie_legacy_int_handler, + rk_pcie); + /* Unmask all legacy interrupt from INTA~INTD */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, + UNMASK_ALL_LEGACY_INT); + } else { + dev_info(dev, "missing legacy IRQ resource\n"); + } + } + + rk_pcie->hot_rst_wq = create_singlethread_workqueue("rk_pcie_hot_rst_wq"); + if (!rk_pcie->hot_rst_wq) { + dev_err(dev, "failed to create hot_rst workqueue\n"); + return -ENOMEM; + } + INIT_WORK(&rk_pcie->hot_rst_work, rk_pcie_hot_rst_work); + + return 0; +} + static int rk_pcie_really_probe(void *p) { struct platform_device *pdev = p; @@ -1125,8 +1228,8 @@ static int rk_pcie_really_probe(void *p) const struct of_device_id *match; const struct rk_pcie_of_data *data; u32 val = 0; - int irq; + /* 1. resource initialization */ match = of_match_device(rk_pcie_of_match, dev); if (!match) { ret = -EINVAL; @@ -1147,22 +1250,21 @@ static int rk_pcie_really_probe(void *p) goto release_driver; } + /* 2. variables assignment */ + rk_pcie->pci = pci; + rk_pcie->msi_vector_num = data ? data->msi_vector_num : 0; pci->dev = dev; pci->ops = &dw_pcie_ops; + platform_set_drvdata(pdev, rk_pcie); - if (data) - rk_pcie->msi_vector_num = data->msi_vector_num; - rk_pcie->pci = pci; - - if (device_property_read_bool(dev, "rockchip,bifurcation")) - rk_pcie->bifurcation = true; - + /* 3. firmware resource */ ret = rk_pcie_resource_get(pdev, rk_pcie); if (ret) { - dev_err(dev, "resource init failed\n"); + dev_err_probe(dev, ret, "resource init failed\n"); goto release_driver; } + /* 4. hardware io settings */ if (!IS_ERR_OR_NULL(rk_pcie->prsnt_gpio)) { if (!gpiod_get_value(rk_pcie->prsnt_gpio)) { dev_info(dev, "device isn't present\n"); @@ -1171,137 +1273,57 @@ static int rk_pcie_really_probe(void *p) } } - rk_pcie->supports_clkreq = device_property_read_bool(dev, "supports-clkreq"); - - if (device_property_read_bool(dev, "hotplug-gpios") || - device_property_read_bool(dev, "hotplug-gpio")) { - rk_pcie->slot_pluggable = true; - dev_info(dev, "support hotplug-gpios!\n"); - } - -retry_regulator: - /* DON'T MOVE ME: must be enable before phy init */ - rk_pcie->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3"); - if (IS_ERR(rk_pcie->vpcie3v3)) { - if (PTR_ERR(rk_pcie->vpcie3v3) != -ENODEV) { - if (IS_ENABLED(CONFIG_PCIE_RK_THREADED_INIT)) { - /* Deferred but in threaded context for most 10s */ - msleep(20); - if (++val < 500) - goto retry_regulator; - } - - ret = PTR_ERR(rk_pcie->vpcie3v3); - goto release_driver; - } - - dev_info(dev, "no vpcie3v3 regulator found\n"); - } - ret = rk_pcie_enable_power(rk_pcie); if (ret) goto release_driver; - ret = rk_pcie_phy_init(rk_pcie); + reset_control_deassert(rk_pcie->rsts); + + ret = clk_bulk_prepare_enable(rk_pcie->clk_cnt, rk_pcie->clks); if (ret) { - dev_err(dev, "phy init failed\n"); + dev_err_probe(dev, ret, "clock init failed\n"); goto disable_vpcie3v3; } - rk_pcie->rsts = devm_reset_control_array_get_exclusive(dev); - if (IS_ERR(rk_pcie->rsts)) { - ret = PTR_ERR(rk_pcie->rsts); - dev_err(dev, "failed to get reset lines\n"); - goto disable_phy; - } - - reset_control_deassert(rk_pcie->rsts); - - ret = rk_pcie_clk_init(rk_pcie); + ret = rk_pcie_phy_init(rk_pcie); if (ret) { - dev_err(dev, "clock init failed\n"); - goto disable_phy; - } - - /* - * Misc interrupts was masked by default. However, they will be - * unmasked by FW before jumpping into kernel. Mask all misc interrupts, - * as we don't need to ack them before registering irq. And they will be - * unmasked later. - */ - rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0xffffffff); - - ret = rk_pcie_request_sys_irq(rk_pcie, pdev); - if (ret) { - dev_err(dev, "pcie irq init failed\n"); + dev_err_probe(dev, ret, "phy init failed\n"); goto disable_clk; } - platform_set_drvdata(pdev, rk_pcie); + /* 5. signal test and capability settings */ + if (rk_pcie->is_lpbk) { + val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL); + val |= PORT_LINK_LPBK_ENABLE; + dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val); + } + + if (rk_pcie->is_comp && rk_pcie->comp_prst[0]) { + val = dw_pcie_readl_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS); + val |= BIT(4) | rk_pcie->comp_prst[0] | (rk_pcie->comp_prst[1] << 12); + dw_pcie_writel_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS, val); + } + + /* Enable RASDES Error event by default */ + val = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_VNDR); + if (!val) { + dev_err(pci->dev, "Unable to find RASDES CAP!\n"); + } else { + dw_pcie_writel_dbi(pci, val + 8, 0x1c); + dw_pcie_writel_dbi(pci, val + 8, 0x3); + rk_pcie->have_rasdes = true; + } + + /* 6. software process */ + ret = rk_pcie_init_irq_and_wq(rk_pcie, pdev); + if (ret) + goto disable_phy; dw_pcie_dbi_ro_wr_en(pci); rk_pcie_fast_link_setup(rk_pcie); - /* Legacy interrupt is optional */ - ret = rk_pcie_init_irq_domain(rk_pcie); - if (!ret) { - irq = platform_get_irq_byname(pdev, "legacy"); - if (irq >= 0) { - irq_set_chained_handler_and_data(irq, rk_pcie_legacy_int_handler, - rk_pcie); - /* Unmask all legacy interrupt from INTA~INTD */ - rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, - UNMASK_ALL_LEGACY_INT); - } else { - dev_info(dev, "missing legacy IRQ resource\n"); - } - } - - /* Set PCIe RC mode */ - rk_pcie_set_mode(rk_pcie); - - /* Force into loopback master mode */ - if (device_property_read_bool(dev, "rockchip,lpbk-master")) { - val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL); - val |= PORT_LINK_LPBK_ENABLE; - dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val); - rk_pcie->is_signal_test = true; - } - - /* - * Force into compliance mode - * comp_prst is a two dimensional array of which the first element - * stands for speed mode, and the second one is preset value encoding: - * [0] 0->SMA tool control the signal switch, 1/2/3 is for manual Gen setting - * [1] transmitter setting for manual Gen setting, valid only if [0] isn't zero. - */ - if (!device_property_read_u32_array(dev, "rockchip,compliance-mode", - rk_pcie->comp_prst, 2)) { - BUG_ON(rk_pcie->comp_prst[0] > 3 || rk_pcie->comp_prst[1] > 10); - if (!rk_pcie->comp_prst[0]) { - dev_info(dev, "Auto compliance mode for SMA tool.\n"); - } else { - dev_info(dev, "compliance mode for soldered board Gen%d, P%d.\n", - rk_pcie->comp_prst[0], rk_pcie->comp_prst[1]); - val = dw_pcie_readl_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS); - val |= BIT(4) | rk_pcie->comp_prst[0] | (rk_pcie->comp_prst[1] << 12); - dw_pcie_writel_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS, val); - } - rk_pcie->is_signal_test = true; - } - - /* Skip waiting for training to pass in system PM routine */ - if (device_property_read_bool(dev, "rockchip,skip-scan-in-resume")) - rk_pcie->skip_scan_in_resume = true; - - rk_pcie->hot_rst_wq = create_singlethread_workqueue("rk_pcie_hot_rst_wq"); - if (!rk_pcie->hot_rst_wq) { - dev_err(dev, "failed to create hot_rst workqueue\n"); - ret = -ENOMEM; - goto remove_irq_domain; - } - INIT_WORK(&rk_pcie->hot_rst_work, rk_pcie_hot_rst_work); + rk_pcie_set_rc_mode(rk_pcie); ret = rk_add_pcie_port(rk_pcie, pdev); @@ -1309,7 +1331,7 @@ retry_regulator: return 0; if (ret && !rk_pcie->slot_pluggable) - goto remove_rst_wq; + goto deinit_irq_and_wq; if (rk_pcie->slot_pluggable) { rk_pcie->hp_slot.plat_ops = &rk_pcie_gpio_hp_plat_ops; @@ -1327,50 +1349,31 @@ retry_regulator: ret = rk_pcie_init_dma_trx(rk_pcie); if (ret) { - dev_err(dev, "failed to add dma extension\n"); - goto remove_rst_wq; + dev_err_probe(dev, ret, "failed to add dma extension\n"); + goto deinit_irq_and_wq; } - if (rk_pcie->dma_obj) { - rk_pcie->dma_obj->start_dma_func = rk_pcie_start_dma_dwc; - rk_pcie->dma_obj->config_dma_func = rk_pcie_config_dma_dwc; - } + ret = rockchip_pcie_debugfs_init(rk_pcie); + if (ret < 0) + dev_err_probe(dev, ret, "failed to setup debugfs\n"); dw_pcie_dbi_ro_wr_dis(pci); + /* 7. framework misc settings */ device_init_wakeup(dev, true); - - /* Enable async system PM for multiports SoC */ - device_enable_async_suspend(dev); - - if (IS_ENABLED(CONFIG_DEBUG_FS)) { - ret = rockchip_pcie_debugfs_init(rk_pcie); - if (ret < 0) - dev_err(dev, "failed to setup debugfs: %d\n", ret); - - /* Enable RASDES Error event by default */ - val = dw_pcie_find_ext_capability(rk_pcie->pci, PCI_EXT_CAP_ID_VNDR); - if (!val) { - dev_err(dev, "Not able to find RASDES CAP!\n"); - return 0; - } - - dw_pcie_writel_dbi(rk_pcie->pci, val + 8, 0x1c); - dw_pcie_writel_dbi(rk_pcie->pci, val + 8, 0x3); - } + device_enable_async_suspend(dev); /* Enable async system PM for multiports SoC */ return 0; -remove_rst_wq: +deinit_irq_and_wq: destroy_workqueue(rk_pcie->hot_rst_wq); -remove_irq_domain: if (rk_pcie->irq_domain) irq_domain_remove(rk_pcie->irq_domain); -disable_clk: - clk_bulk_disable_unprepare(rk_pcie->clk_cnt, rk_pcie->clks); disable_phy: phy_power_off(rk_pcie->phy); phy_exit(rk_pcie->phy); +disable_clk: + clk_bulk_disable_unprepare(rk_pcie->clk_cnt, rk_pcie->clks); disable_vpcie3v3: rk_pcie_disable_power(rk_pcie); release_driver: @@ -1386,10 +1389,8 @@ static int rk_pcie_probe(struct platform_device *pdev) struct task_struct *tsk; tsk = kthread_run(rk_pcie_really_probe, pdev, "rk-pcie"); - if (IS_ERR(tsk)) { - dev_err(&pdev->dev, "start rk-pcie thread failed\n"); - return PTR_ERR(tsk); - } + if (IS_ERR(tsk)) + return dev_err_probe(&pdev->dev, PTR_ERR(tsk), "start rk-pcie thread failed\n"); return 0; } @@ -1601,8 +1602,7 @@ static int __maybe_unused rockchip_dw_pcie_resume(struct device *dev) rk_pcie_fast_link_setup(rk_pcie); - /* Set PCIe RC mode */ - rk_pcie_set_mode(rk_pcie); + rk_pcie_set_rc_mode(rk_pcie); dw_pcie_setup_rc(&rk_pcie->pci->pp); diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c index e918decb3735..54e93db1621a 100644 --- a/fs/exfat/balloc.c +++ b/fs/exfat/balloc.c @@ -110,10 +110,14 @@ int exfat_load_bitmap(struct super_block *sb) return -EIO; type = exfat_get_entry_type(ep); - if (type == TYPE_UNUSED) + if (type == TYPE_UNUSED) { + brelse(bh); break; - if (type != TYPE_BITMAP) + } + if (type != TYPE_BITMAP) { + brelse(bh); continue; + } if (ep->dentry.bitmap.flags == 0x0) { int err; diff --git a/sound/soc/rockchip/rockchip_multicodecs.c b/sound/soc/rockchip/rockchip_multicodecs.c index 0b182191f72d..8c3bb17f2056 100644 --- a/sound/soc/rockchip/rockchip_multicodecs.c +++ b/sound/soc/rockchip/rockchip_multicodecs.c @@ -76,6 +76,10 @@ struct multicodecs_data { const struct adc_keys_button *map; struct input_dev *input; struct input_dev_poller *poller; + int slots; + int slot_width; + unsigned int tx_slot_mask; + unsigned int rx_slot_mask; }; static const unsigned int headset_extcon_cable[] = { @@ -399,7 +403,9 @@ static int rk_dailink_init(struct snd_soc_pcm_runtime *rtd) struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_card *card = rtd->card; struct snd_soc_jack *jack_headset; - int ret, irq; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai; + int ret, irq, i; struct snd_soc_jack_pin *pins; struct snd_soc_jack_zone *zones; struct snd_soc_jack_pin jack_pins[] = { @@ -427,6 +433,30 @@ static int rk_dailink_init(struct snd_soc_pcm_runtime *rtd) } }; + if (mc_data->slots) { + ret = snd_soc_dai_set_tdm_slot(cpu_dai, + mc_data->tx_slot_mask, + mc_data->rx_slot_mask, + mc_data->slots, + mc_data->slot_width); + if (ret && ret != -EOPNOTSUPP) { + dev_err(card->dev, "cpu_dai: set_tdm_slot error\n"); + return ret; + } + + for_each_rtd_codec_dais(rtd, i, codec_dai) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, + mc_data->tx_slot_mask, + mc_data->rx_slot_mask, + mc_data->slots, + mc_data->slot_width); + if (ret && ret != -EOPNOTSUPP) { + dev_err(card->dev, "codec_dai: set_tdm_slot error\n"); + return ret; + } + } + } + if ((!mc_data->codec_hp_det) && (gpiod_to_irq(mc_data->hp_det_gpio) < 0)) { dev_info(card->dev, "Don't need to map headset detect gpio to irq\n"); return 0; @@ -804,6 +834,15 @@ static int rk_multicodecs_probe(struct platform_device *pdev) mc_data->dai_link[0].platforms->of_node = mc_data->dai_link[0].cpus->of_node; + ret = snd_soc_of_parse_tdm_slot(np, + &mc_data->tx_slot_mask, + &mc_data->rx_slot_mask, + &mc_data->slots, + &mc_data->slot_width); + if (ret < 0) { + dev_err(&pdev->dev, "snd_soc_of_parse_tdm_slot failed: %d\n", ret); + return ret; + } asrc_np = of_parse_phandle(np, "rockchip,asrc", 0); if (asrc_np) { mc_data->dai_link[1].cpus->of_node = asrc_np;