16b1baefeSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2c1167ceeSYang Shen /*
3f410f157SJesse Brandeburg * DOC: Cadence GEM PCI wrapper.
483a77e9eSBartosz Folta *
55d75c043SAlexander A. Klimov * Copyright (C) 2016 Cadence Design Systems - https://www.cadence.com
683a77e9eSBartosz Folta *
783a77e9eSBartosz Folta * Authors: Rafal Ozieblo <rafalo@cadence.com>
883a77e9eSBartosz Folta * Bartosz Folta <bfolta@cadence.com>
983a77e9eSBartosz Folta */
1083a77e9eSBartosz Folta
1183a77e9eSBartosz Folta #include <linux/clk.h>
1283a77e9eSBartosz Folta #include <linux/clk-provider.h>
1383a77e9eSBartosz Folta #include <linux/etherdevice.h>
1483a77e9eSBartosz Folta #include <linux/module.h>
1583a77e9eSBartosz Folta #include <linux/pci.h>
1683a77e9eSBartosz Folta #include <linux/platform_device.h>
1783a77e9eSBartosz Folta #include "macb.h"
1883a77e9eSBartosz Folta
1983a77e9eSBartosz Folta #define PCI_DRIVER_NAME "macb_pci"
2083a77e9eSBartosz Folta #define PLAT_DRIVER_NAME "macb"
2183a77e9eSBartosz Folta
2283a77e9eSBartosz Folta #define CDNS_VENDOR_ID 0x17cd
2383a77e9eSBartosz Folta #define CDNS_DEVICE_ID 0xe007
2483a77e9eSBartosz Folta
2583a77e9eSBartosz Folta #define GEM_PCLK_RATE 50000000
2683a77e9eSBartosz Folta #define GEM_HCLK_RATE 50000000
2783a77e9eSBartosz Folta
macb_probe(struct pci_dev * pdev,const struct pci_device_id * id)2883a77e9eSBartosz Folta static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2983a77e9eSBartosz Folta {
3083a77e9eSBartosz Folta int err;
3183a77e9eSBartosz Folta struct platform_device *plat_dev;
3283a77e9eSBartosz Folta struct platform_device_info plat_info;
3383a77e9eSBartosz Folta struct macb_platform_data plat_data;
3483a77e9eSBartosz Folta struct resource res[2];
3583a77e9eSBartosz Folta
3683a77e9eSBartosz Folta /* enable pci device */
37515028feSBartosz Folta err = pcim_enable_device(pdev);
3883a77e9eSBartosz Folta if (err < 0) {
39515028feSBartosz Folta dev_err(&pdev->dev, "Enabling PCI device has failed: %d", err);
40515028feSBartosz Folta return err;
4183a77e9eSBartosz Folta }
4283a77e9eSBartosz Folta
4383a77e9eSBartosz Folta pci_set_master(pdev);
4483a77e9eSBartosz Folta
4583a77e9eSBartosz Folta /* set up resources */
4683a77e9eSBartosz Folta memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
47515028feSBartosz Folta res[0].start = pci_resource_start(pdev, 0);
48515028feSBartosz Folta res[0].end = pci_resource_end(pdev, 0);
4983a77e9eSBartosz Folta res[0].name = PCI_DRIVER_NAME;
5083a77e9eSBartosz Folta res[0].flags = IORESOURCE_MEM;
51515028feSBartosz Folta res[1].start = pci_irq_vector(pdev, 0);
5283a77e9eSBartosz Folta res[1].name = PCI_DRIVER_NAME;
5383a77e9eSBartosz Folta res[1].flags = IORESOURCE_IRQ;
5483a77e9eSBartosz Folta
55515028feSBartosz Folta dev_info(&pdev->dev, "EMAC physical base addr: %pa\n",
56515028feSBartosz Folta &res[0].start);
5783a77e9eSBartosz Folta
5883a77e9eSBartosz Folta /* set up macb platform data */
5983a77e9eSBartosz Folta memset(&plat_data, 0, sizeof(plat_data));
6083a77e9eSBartosz Folta
6183a77e9eSBartosz Folta /* initialize clocks */
6283a77e9eSBartosz Folta plat_data.pclk = clk_register_fixed_rate(&pdev->dev, "pclk", NULL, 0,
6383a77e9eSBartosz Folta GEM_PCLK_RATE);
6483a77e9eSBartosz Folta if (IS_ERR(plat_data.pclk)) {
6583a77e9eSBartosz Folta err = PTR_ERR(plat_data.pclk);
6683a77e9eSBartosz Folta goto err_pclk_register;
6783a77e9eSBartosz Folta }
6883a77e9eSBartosz Folta
6983a77e9eSBartosz Folta plat_data.hclk = clk_register_fixed_rate(&pdev->dev, "hclk", NULL, 0,
7083a77e9eSBartosz Folta GEM_HCLK_RATE);
7183a77e9eSBartosz Folta if (IS_ERR(plat_data.hclk)) {
7283a77e9eSBartosz Folta err = PTR_ERR(plat_data.hclk);
7383a77e9eSBartosz Folta goto err_hclk_register;
7483a77e9eSBartosz Folta }
7583a77e9eSBartosz Folta
7683a77e9eSBartosz Folta /* set up platform device info */
7783a77e9eSBartosz Folta memset(&plat_info, 0, sizeof(plat_info));
7883a77e9eSBartosz Folta plat_info.parent = &pdev->dev;
7983a77e9eSBartosz Folta plat_info.fwnode = pdev->dev.fwnode;
8083a77e9eSBartosz Folta plat_info.name = PLAT_DRIVER_NAME;
8183a77e9eSBartosz Folta plat_info.id = pdev->devfn;
8283a77e9eSBartosz Folta plat_info.res = res;
8383a77e9eSBartosz Folta plat_info.num_res = ARRAY_SIZE(res);
8483a77e9eSBartosz Folta plat_info.data = &plat_data;
8583a77e9eSBartosz Folta plat_info.size_data = sizeof(plat_data);
86515028feSBartosz Folta plat_info.dma_mask = pdev->dma_mask;
8783a77e9eSBartosz Folta
8883a77e9eSBartosz Folta /* register platform device */
8983a77e9eSBartosz Folta plat_dev = platform_device_register_full(&plat_info);
9083a77e9eSBartosz Folta if (IS_ERR(plat_dev)) {
9183a77e9eSBartosz Folta err = PTR_ERR(plat_dev);
9283a77e9eSBartosz Folta goto err_plat_dev_register;
9383a77e9eSBartosz Folta }
9483a77e9eSBartosz Folta
9583a77e9eSBartosz Folta pci_set_drvdata(pdev, plat_dev);
9683a77e9eSBartosz Folta
9783a77e9eSBartosz Folta return 0;
9883a77e9eSBartosz Folta
9983a77e9eSBartosz Folta err_plat_dev_register:
10083a77e9eSBartosz Folta clk_unregister(plat_data.hclk);
10183a77e9eSBartosz Folta
10283a77e9eSBartosz Folta err_hclk_register:
10383a77e9eSBartosz Folta clk_unregister(plat_data.pclk);
10483a77e9eSBartosz Folta
10583a77e9eSBartosz Folta err_pclk_register:
10683a77e9eSBartosz Folta return err;
10783a77e9eSBartosz Folta }
10883a77e9eSBartosz Folta
macb_remove(struct pci_dev * pdev)10983a77e9eSBartosz Folta static void macb_remove(struct pci_dev *pdev)
11083a77e9eSBartosz Folta {
11183a77e9eSBartosz Folta struct platform_device *plat_dev = pci_get_drvdata(pdev);
11283a77e9eSBartosz Folta struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev);
11383a77e9eSBartosz Folta
11483a77e9eSBartosz Folta clk_unregister(plat_data->pclk);
11583a77e9eSBartosz Folta clk_unregister(plat_data->hclk);
116*d82d5303STong Zhang platform_device_unregister(plat_dev);
11783a77e9eSBartosz Folta }
11883a77e9eSBartosz Folta
119c744cf5bSArvind Yadav static const struct pci_device_id dev_id_table[] = {
12083a77e9eSBartosz Folta { PCI_DEVICE(CDNS_VENDOR_ID, CDNS_DEVICE_ID), },
12183a77e9eSBartosz Folta { 0, }
12283a77e9eSBartosz Folta };
12383a77e9eSBartosz Folta
12483a77e9eSBartosz Folta static struct pci_driver macb_pci_driver = {
12583a77e9eSBartosz Folta .name = PCI_DRIVER_NAME,
12683a77e9eSBartosz Folta .id_table = dev_id_table,
12783a77e9eSBartosz Folta .probe = macb_probe,
12883a77e9eSBartosz Folta .remove = macb_remove,
12983a77e9eSBartosz Folta };
13083a77e9eSBartosz Folta
13183a77e9eSBartosz Folta module_pci_driver(macb_pci_driver);
13283a77e9eSBartosz Folta MODULE_DEVICE_TABLE(pci, dev_id_table);
13383a77e9eSBartosz Folta MODULE_LICENSE("GPL");
13483a77e9eSBartosz Folta MODULE_DESCRIPTION("Cadence NIC PCI wrapper");
135