497 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * PCIe host controller driver for Amlogic MESON SoCs4 *5 * Copyright (c) 2018 Amlogic, inc.6 * Author: Yue Wang <yue.wang@amlogic.com>7 */8 9#include <linux/clk.h>10#include <linux/delay.h>11#include <linux/gpio/consumer.h>12#include <linux/pci.h>13#include <linux/platform_device.h>14#include <linux/reset.h>15#include <linux/resource.h>16#include <linux/types.h>17#include <linux/phy/phy.h>18#include <linux/mod_devicetable.h>19#include <linux/module.h>20 21#include "pcie-designware.h"22 23#define to_meson_pcie(x) dev_get_drvdata((x)->dev)24 25#define PCIE_CAP_MAX_PAYLOAD_SIZE(x) ((x) << 5)26#define PCIE_CAP_MAX_READ_REQ_SIZE(x) ((x) << 12)27 28/* PCIe specific config registers */29#define PCIE_CFG0 0x030#define APP_LTSSM_ENABLE BIT(7)31 32#define PCIE_CFG_STATUS12 0x3033#define IS_SMLH_LINK_UP(x) ((x) & (1 << 6))34#define IS_RDLH_LINK_UP(x) ((x) & (1 << 16))35#define IS_LTSSM_UP(x) ((((x) >> 10) & 0x1f) == 0x11)36 37#define PCIE_CFG_STATUS17 0x4438#define PM_CURRENT_STATE(x) (((x) >> 7) & 0x1)39 40#define WAIT_LINKUP_TIMEOUT 400041#define PORT_CLK_RATE 100000000UL42#define MAX_PAYLOAD_SIZE 25643#define MAX_READ_REQ_SIZE 25644#define PCIE_RESET_DELAY 50045#define PCIE_SHARED_RESET 146#define PCIE_NORMAL_RESET 047 48enum pcie_data_rate {49 PCIE_GEN1,50 PCIE_GEN2,51 PCIE_GEN3,52 PCIE_GEN453};54 55struct meson_pcie_clk_res {56 struct clk *clk;57 struct clk *port_clk;58 struct clk *general_clk;59};60 61struct meson_pcie_rc_reset {62 struct reset_control *port;63 struct reset_control *apb;64};65 66struct meson_pcie {67 struct dw_pcie pci;68 void __iomem *cfg_base;69 struct meson_pcie_clk_res clk_res;70 struct meson_pcie_rc_reset mrst;71 struct gpio_desc *reset_gpio;72 struct phy *phy;73};74 75static struct reset_control *meson_pcie_get_reset(struct meson_pcie *mp,76 const char *id,77 u32 reset_type)78{79 struct device *dev = mp->pci.dev;80 struct reset_control *reset;81 82 if (reset_type == PCIE_SHARED_RESET)83 reset = devm_reset_control_get_shared(dev, id);84 else85 reset = devm_reset_control_get(dev, id);86 87 return reset;88}89 90static int meson_pcie_get_resets(struct meson_pcie *mp)91{92 struct meson_pcie_rc_reset *mrst = &mp->mrst;93 94 mrst->port = meson_pcie_get_reset(mp, "port", PCIE_NORMAL_RESET);95 if (IS_ERR(mrst->port))96 return PTR_ERR(mrst->port);97 reset_control_deassert(mrst->port);98 99 mrst->apb = meson_pcie_get_reset(mp, "apb", PCIE_SHARED_RESET);100 if (IS_ERR(mrst->apb))101 return PTR_ERR(mrst->apb);102 reset_control_deassert(mrst->apb);103 104 return 0;105}106 107static int meson_pcie_get_mems(struct platform_device *pdev,108 struct meson_pcie *mp)109{110 struct dw_pcie *pci = &mp->pci;111 112 pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "elbi");113 if (IS_ERR(pci->dbi_base))114 return PTR_ERR(pci->dbi_base);115 116 mp->cfg_base = devm_platform_ioremap_resource_byname(pdev, "cfg");117 if (IS_ERR(mp->cfg_base))118 return PTR_ERR(mp->cfg_base);119 120 return 0;121}122 123static int meson_pcie_power_on(struct meson_pcie *mp)124{125 int ret = 0;126 127 ret = phy_init(mp->phy);128 if (ret)129 return ret;130 131 ret = phy_power_on(mp->phy);132 if (ret) {133 phy_exit(mp->phy);134 return ret;135 }136 137 return 0;138}139 140static void meson_pcie_power_off(struct meson_pcie *mp)141{142 phy_power_off(mp->phy);143 phy_exit(mp->phy);144}145 146static int meson_pcie_reset(struct meson_pcie *mp)147{148 struct meson_pcie_rc_reset *mrst = &mp->mrst;149 int ret = 0;150 151 ret = phy_reset(mp->phy);152 if (ret)153 return ret;154 155 reset_control_assert(mrst->port);156 reset_control_assert(mrst->apb);157 udelay(PCIE_RESET_DELAY);158 reset_control_deassert(mrst->port);159 reset_control_deassert(mrst->apb);160 udelay(PCIE_RESET_DELAY);161 162 return 0;163}164 165static inline void meson_pcie_disable_clock(void *data)166{167 struct clk *clk = data;168 169 clk_disable_unprepare(clk);170}171 172static inline struct clk *meson_pcie_probe_clock(struct device *dev,173 const char *id, u64 rate)174{175 struct clk *clk;176 int ret;177 178 clk = devm_clk_get(dev, id);179 if (IS_ERR(clk))180 return clk;181 182 if (rate) {183 ret = clk_set_rate(clk, rate);184 if (ret) {185 dev_err(dev, "set clk rate failed, ret = %d\n", ret);186 return ERR_PTR(ret);187 }188 }189 190 ret = clk_prepare_enable(clk);191 if (ret) {192 dev_err(dev, "couldn't enable clk\n");193 return ERR_PTR(ret);194 }195 196 devm_add_action_or_reset(dev, meson_pcie_disable_clock, clk);197 198 return clk;199}200 201static int meson_pcie_probe_clocks(struct meson_pcie *mp)202{203 struct device *dev = mp->pci.dev;204 struct meson_pcie_clk_res *res = &mp->clk_res;205 206 res->port_clk = meson_pcie_probe_clock(dev, "port", PORT_CLK_RATE);207 if (IS_ERR(res->port_clk))208 return PTR_ERR(res->port_clk);209 210 res->general_clk = meson_pcie_probe_clock(dev, "general", 0);211 if (IS_ERR(res->general_clk))212 return PTR_ERR(res->general_clk);213 214 res->clk = meson_pcie_probe_clock(dev, "pclk", 0);215 if (IS_ERR(res->clk))216 return PTR_ERR(res->clk);217 218 return 0;219}220 221static inline u32 meson_cfg_readl(struct meson_pcie *mp, u32 reg)222{223 return readl(mp->cfg_base + reg);224}225 226static inline void meson_cfg_writel(struct meson_pcie *mp, u32 val, u32 reg)227{228 writel(val, mp->cfg_base + reg);229}230 231static void meson_pcie_assert_reset(struct meson_pcie *mp)232{233 gpiod_set_value_cansleep(mp->reset_gpio, 1);234 udelay(500);235 gpiod_set_value_cansleep(mp->reset_gpio, 0);236}237 238static void meson_pcie_ltssm_enable(struct meson_pcie *mp)239{240 u32 val;241 242 val = meson_cfg_readl(mp, PCIE_CFG0);243 val |= APP_LTSSM_ENABLE;244 meson_cfg_writel(mp, val, PCIE_CFG0);245}246 247static int meson_size_to_payload(struct meson_pcie *mp, int size)248{249 struct device *dev = mp->pci.dev;250 251 /*252 * dwc supports 2^(val+7) payload size, which val is 0~5 default to 1.253 * So if input size is not 2^order alignment or less than 2^7 or bigger254 * than 2^12, just set to default size 2^(1+7).255 */256 if (!is_power_of_2(size) || size < 128 || size > 4096) {257 dev_warn(dev, "payload size %d, set to default 256\n", size);258 return 1;259 }260 261 return fls(size) - 8;262}263 264static void meson_set_max_payload(struct meson_pcie *mp, int size)265{266 struct dw_pcie *pci = &mp->pci;267 u32 val;268 u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);269 int max_payload_size = meson_size_to_payload(mp, size);270 271 val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_DEVCTL);272 val &= ~PCI_EXP_DEVCTL_PAYLOAD;273 dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);274 275 val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_DEVCTL);276 val |= PCIE_CAP_MAX_PAYLOAD_SIZE(max_payload_size);277 dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);278}279 280static void meson_set_max_rd_req_size(struct meson_pcie *mp, int size)281{282 struct dw_pcie *pci = &mp->pci;283 u32 val;284 u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);285 int max_rd_req_size = meson_size_to_payload(mp, size);286 287 val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_DEVCTL);288 val &= ~PCI_EXP_DEVCTL_READRQ;289 dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);290 291 val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_DEVCTL);292 val |= PCIE_CAP_MAX_READ_REQ_SIZE(max_rd_req_size);293 dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);294}295 296static int meson_pcie_start_link(struct dw_pcie *pci)297{298 struct meson_pcie *mp = to_meson_pcie(pci);299 300 meson_pcie_ltssm_enable(mp);301 meson_pcie_assert_reset(mp);302 303 return 0;304}305 306static int meson_pcie_rd_own_conf(struct pci_bus *bus, u32 devfn,307 int where, int size, u32 *val)308{309 int ret;310 311 ret = pci_generic_config_read(bus, devfn, where, size, val);312 if (ret != PCIBIOS_SUCCESSFUL)313 return ret;314 315 /*316 * There is a bug in the MESON AXG PCIe controller whereby software317 * cannot program the PCI_CLASS_DEVICE register, so we must fabricate318 * the return value in the config accessors.319 */320 if ((where & ~3) == PCI_CLASS_REVISION) {321 if (size <= 2)322 *val = (*val & ((1 << (size * 8)) - 1)) << (8 * (where & 3));323 *val &= ~0xffffff00;324 *val |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8;325 if (size <= 2)326 *val = (*val >> (8 * (where & 3))) & ((1 << (size * 8)) - 1);327 }328 329 return PCIBIOS_SUCCESSFUL;330}331 332static struct pci_ops meson_pci_ops = {333 .map_bus = dw_pcie_own_conf_map_bus,334 .read = meson_pcie_rd_own_conf,335 .write = pci_generic_config_write,336};337 338static int meson_pcie_link_up(struct dw_pcie *pci)339{340 struct meson_pcie *mp = to_meson_pcie(pci);341 struct device *dev = pci->dev;342 u32 speed_okay = 0;343 u32 cnt = 0;344 u32 state12, state17, smlh_up, ltssm_up, rdlh_up;345 346 do {347 state12 = meson_cfg_readl(mp, PCIE_CFG_STATUS12);348 state17 = meson_cfg_readl(mp, PCIE_CFG_STATUS17);349 smlh_up = IS_SMLH_LINK_UP(state12);350 rdlh_up = IS_RDLH_LINK_UP(state12);351 ltssm_up = IS_LTSSM_UP(state12);352 353 if (PM_CURRENT_STATE(state17) < PCIE_GEN3)354 speed_okay = 1;355 356 if (smlh_up)357 dev_dbg(dev, "smlh_link_up is on\n");358 if (rdlh_up)359 dev_dbg(dev, "rdlh_link_up is on\n");360 if (ltssm_up)361 dev_dbg(dev, "ltssm_up is on\n");362 if (speed_okay)363 dev_dbg(dev, "speed_okay\n");364 365 if (smlh_up && rdlh_up && ltssm_up && speed_okay)366 return 1;367 368 cnt++;369 370 udelay(10);371 } while (cnt < WAIT_LINKUP_TIMEOUT);372 373 dev_err(dev, "error: wait linkup timeout\n");374 return 0;375}376 377static int meson_pcie_host_init(struct dw_pcie_rp *pp)378{379 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);380 struct meson_pcie *mp = to_meson_pcie(pci);381 382 pp->bridge->ops = &meson_pci_ops;383 384 meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);385 meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);386 387 return 0;388}389 390static const struct dw_pcie_host_ops meson_pcie_host_ops = {391 .init = meson_pcie_host_init,392};393 394static const struct dw_pcie_ops dw_pcie_ops = {395 .link_up = meson_pcie_link_up,396 .start_link = meson_pcie_start_link,397};398 399static int meson_pcie_probe(struct platform_device *pdev)400{401 struct device *dev = &pdev->dev;402 struct dw_pcie *pci;403 struct meson_pcie *mp;404 int ret;405 406 mp = devm_kzalloc(dev, sizeof(*mp), GFP_KERNEL);407 if (!mp)408 return -ENOMEM;409 410 pci = &mp->pci;411 pci->dev = dev;412 pci->ops = &dw_pcie_ops;413 pci->pp.ops = &meson_pcie_host_ops;414 pci->num_lanes = 1;415 416 mp->phy = devm_phy_get(dev, "pcie");417 if (IS_ERR(mp->phy)) {418 dev_err(dev, "get phy failed, %ld\n", PTR_ERR(mp->phy));419 return PTR_ERR(mp->phy);420 }421 422 mp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);423 if (IS_ERR(mp->reset_gpio)) {424 dev_err(dev, "get reset gpio failed\n");425 return PTR_ERR(mp->reset_gpio);426 }427 428 ret = meson_pcie_get_resets(mp);429 if (ret) {430 dev_err(dev, "get reset resource failed, %d\n", ret);431 return ret;432 }433 434 ret = meson_pcie_get_mems(pdev, mp);435 if (ret) {436 dev_err(dev, "get memory resource failed, %d\n", ret);437 return ret;438 }439 440 ret = meson_pcie_power_on(mp);441 if (ret) {442 dev_err(dev, "phy power on failed, %d\n", ret);443 return ret;444 }445 446 ret = meson_pcie_reset(mp);447 if (ret) {448 dev_err(dev, "reset failed, %d\n", ret);449 goto err_phy;450 }451 452 ret = meson_pcie_probe_clocks(mp);453 if (ret) {454 dev_err(dev, "init clock resources failed, %d\n", ret);455 goto err_phy;456 }457 458 platform_set_drvdata(pdev, mp);459 460 ret = dw_pcie_host_init(&pci->pp);461 if (ret < 0) {462 dev_err(dev, "Add PCIe port failed, %d\n", ret);463 goto err_phy;464 }465 466 return 0;467 468err_phy:469 meson_pcie_power_off(mp);470 return ret;471}472 473static const struct of_device_id meson_pcie_of_match[] = {474 {475 .compatible = "amlogic,axg-pcie",476 },477 {478 .compatible = "amlogic,g12a-pcie",479 },480 {},481};482MODULE_DEVICE_TABLE(of, meson_pcie_of_match);483 484static struct platform_driver meson_pcie_driver = {485 .probe = meson_pcie_probe,486 .driver = {487 .name = "meson-pcie",488 .of_match_table = meson_pcie_of_match,489 },490};491 492module_platform_driver(meson_pcie_driver);493 494MODULE_AUTHOR("Yue Wang <yue.wang@amlogic.com>");495MODULE_DESCRIPTION("Amlogic PCIe Controller driver");496MODULE_LICENSE("GPL v2");497