Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b23c0ca4 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: stmmac: Add support for smmu enablement"

parents c30b722b 9b43c390
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -33,10 +33,10 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)

	len = nopaged_len - bmax;

	des2 = dma_map_single(priv->device, skb->data,
	des2 = dma_map_single(GET_MEM_PDEV_DEV, skb->data,
			      bmax, DMA_TO_DEVICE);
	desc->des2 = cpu_to_le32(des2);
	if (dma_mapping_error(priv->device, des2))
	if (dma_mapping_error(GET_MEM_PDEV_DEV, des2))
		return -1;
	tx_q->tx_skbuff_dma[entry].buf = des2;
	tx_q->tx_skbuff_dma[entry].len = bmax;
@@ -50,11 +50,11 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)
		desc = tx_q->dma_tx + entry;

		if (len > bmax) {
			des2 = dma_map_single(priv->device,
			des2 = dma_map_single(GET_MEM_PDEV_DEV,
					      (skb->data + bmax * i),
					      bmax, DMA_TO_DEVICE);
			desc->des2 = cpu_to_le32(des2);
			if (dma_mapping_error(priv->device, des2))
			if (dma_mapping_error(GET_MEM_PDEV_DEV, des2))
				return -1;
			tx_q->tx_skbuff_dma[entry].buf = des2;
			tx_q->tx_skbuff_dma[entry].len = bmax;
@@ -63,11 +63,11 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)
			len -= bmax;
			i++;
		} else {
			des2 = dma_map_single(priv->device,
			des2 = dma_map_single(GET_MEM_PDEV_DEV,
					      (skb->data + bmax * i), len,
					      DMA_TO_DEVICE);
			desc->des2 = cpu_to_le32(des2);
			if (dma_mapping_error(priv->device, des2))
			if (dma_mapping_error(GET_MEM_PDEV_DEV, des2))
				return -1;
			tx_q->tx_skbuff_dma[entry].buf = des2;
			tx_q->tx_skbuff_dma[entry].len = len;
+81 −6
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@
#include <linux/ipc_logging.h>
#include <linux/poll.h>
#include <linux/debugfs.h>
#include <linux/dma-iommu.h>
#include <linux/iommu.h>


#include "stmmac.h"
#include "stmmac_platform.h"
@@ -101,6 +104,8 @@

bool phy_intr_en;

struct emac_emb_smmu_cb_ctx emac_emb_smmu_ctx = {0};

static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset)
{
	return readl(ethqos->rgmii_base + offset);
@@ -598,6 +603,64 @@ static int ethqos_phy_intr_enable(struct qcom_ethqos *ethqos)
	return ret;
}

static const struct of_device_id qcom_ethqos_match[] = {
	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_por},
	{ .compatible = "qcom,sdxprairie-ethqos", .data = &emac_v2_3_2_por},
	{ .compatible = "qcom,stmmac-ethqos", },
	{ .compatible = "qcom,emac-smmu-embedded", },
	{ }
};

static void emac_emb_smmu_exit(void)
{
	emac_emb_smmu_ctx.valid = false;
	emac_emb_smmu_ctx.pdev_master = NULL;
	emac_emb_smmu_ctx.smmu_pdev = NULL;
	emac_emb_smmu_ctx.iommu_domain = NULL;
}

static int emac_emb_smmu_cb_probe(struct platform_device *pdev)
{
	int result = 0;
	u32 iova_ap_mapping[2];
	struct device *dev = &pdev->dev;
	int atomic_ctx = 1;
	int fast = 1;
	int bypass = 1;

	ETHQOSDBG("EMAC EMB SMMU CB probe: smmu pdev=%p\n", pdev);

	result = of_property_read_u32_array(dev->of_node,
					    "qcom,iommu-dma-addr-pool",
					    iova_ap_mapping,
					    ARRAY_SIZE(iova_ap_mapping));
	if (result) {
		ETHQOSERR("Failed to read EMB start/size iova addresses\n");
		return result;
	}

	emac_emb_smmu_ctx.smmu_pdev = pdev;

	if (dma_set_mask(dev, DMA_BIT_MASK(32)) ||
	    dma_set_coherent_mask(dev, DMA_BIT_MASK(32))) {
		ETHQOSERR("DMA set 32bit mask failed\n");
		return -EOPNOTSUPP;
	}

	emac_emb_smmu_ctx.valid = true;

	emac_emb_smmu_ctx.iommu_domain =
		iommu_get_domain_for_dev(&emac_emb_smmu_ctx.smmu_pdev->dev);

	ETHQOSINFO("Successfully attached to IOMMU\n");
	if (emac_emb_smmu_ctx.pdev_master)
		goto smmu_probe_done;

smmu_probe_done:
	emac_emb_smmu_ctx.ret = result;
	return result;
}

static int qcom_ethqos_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
@@ -608,6 +671,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
	struct resource *res;
	int ret;

	if (of_device_is_compatible(pdev->dev.of_node,
				    "qcom,emac-smmu-embedded"))
		return emac_emb_smmu_cb_probe(pdev);
	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
	if (ret)
		return ret;
@@ -678,6 +744,20 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
	}
	ETHQOSDBG(": emac_core_version = %d\n", ethqos->emac_ver);

	if (of_property_read_bool(pdev->dev.of_node, "qcom,arm-smmu")) {
		emac_emb_smmu_ctx.pdev_master = pdev;
		ret = of_platform_populate(pdev->dev.of_node,
					   qcom_ethqos_match, NULL, &pdev->dev);
		if (ret)
			ETHQOSERR("Failed to populate EMAC platform\n");
		if (emac_emb_smmu_ctx.ret) {
			ETHQOSERR("smmu probe failed\n");
			of_platform_depopulate(&pdev->dev);
			ret = emac_emb_smmu_ctx.ret;
			emac_emb_smmu_ctx.ret = 0;
		}
	}

	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
	if (ret)
		goto err_clk;
@@ -711,17 +791,12 @@ static int qcom_ethqos_remove(struct platform_device *pdev)

	if (phy_intr_en)
		free_irq(ethqos->phy_intr, ethqos);
	emac_emb_smmu_exit();
	ethqos_disable_regulators(ethqos);

	return ret;
}

static const struct of_device_id qcom_ethqos_match[] = {
	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_por},
	{ .compatible = "qcom,sdxprairie-ethqos", .data = &emac_v2_3_2_por},
	{ .compatible = "qcom,stmmac-ethqos", },
	{ }
};
MODULE_DEVICE_TABLE(of, qcom_ethqos_match);

static struct platform_driver qcom_ethqos_driver = {
+3 −4
Original line number Diff line number Diff line
@@ -6,12 +6,11 @@

#define DRV_NAME "qcom-ethqos"
#define ETHQOSDBG(fmt, args...) \
	pr_debug(DRV_NAME " %s:%d " fmt, __func__, ## args)
	pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
#define ETHQOSERR(fmt, args...) \
	pr_err(DRV_NAME " %s:%d " fmt, __func__, ## args)
	pr_err(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
#define ETHQOSINFO(fmt, args...) \
	pr_info(DRV_NAME " %s:%d " fmt, __func__, ## args)

	pr_info(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
#define RGMII_IO_MACRO_CONFIG		0x0
#define SDCC_HC_REG_DLL_CONFIG		0x4
#define SDCC_HC_REG_DDR_CONFIG		0xC
+54 −5
Original line number Diff line number Diff line
@@ -174,20 +174,69 @@ void ethqos_free_gpios(struct qcom_ethqos *ethqos)
	ethqos->gpio_phy_intr_redirect = -1;
}

int ethqos_init_gpio(struct qcom_ethqos *ethqos)
int ethqos_init_pinctrl(struct device *dev)
{
	struct pinctrl *pinctrl;

	ethqos->gpio_phy_intr_redirect = -1;
	struct pinctrl_state *pinctrl_state;
	int i = 0;
	int num_names;
	const char *name;
	int ret = 0;

	pinctrl = devm_pinctrl_get(&ethqos->pdev->dev);
	pinctrl = devm_pinctrl_get(dev);
	if (IS_ERR_OR_NULL(pinctrl)) {
		ret = PTR_ERR(pinctrl);
		ETHQOSERR("Failed to get pinctrl, err = %d\n", ret);
		return ret;
	}
	ETHQOSDBG("get pinctrl succeed\n");

	num_names = of_property_count_strings(dev->of_node, "pinctrl-names");
	if (num_names < 0) {
		dev_err(dev, "Cannot parse pinctrl-names: %d\n",
			num_names);
		return num_names;
	}

	for (i = 0; i < num_names; i++) {
		ret = of_property_read_string_index(dev->of_node,
						    "pinctrl-names",
						    i, &name);

		if (!strcmp(name, PINCTRL_STATE_DEFAULT))
			continue;

		pinctrl_state = pinctrl_lookup_state(pinctrl, name);
		if (IS_ERR_OR_NULL(pinctrl_state)) {
			ret = PTR_ERR(pinctrl_state);
			ETHQOSERR("lookup_state %s failed %d\n", name, ret);
			return ret;
		}

		ETHQOSINFO("pinctrl_lookup_state %s succeded\n", name);

		ret = pinctrl_select_state(pinctrl, pinctrl_state);
		if (ret) {
			ETHQOSERR("select_state %s failed %d\n", name, ret);
			return ret;
		}

		ETHQOSINFO("pinctrl_select_state %s succeded\n", name);
	}

	return ret;
}

int ethqos_init_gpio(struct qcom_ethqos *ethqos)
{
	int ret = 0;

	ethqos->gpio_phy_intr_redirect = -1;

	ret = ethqos_init_pinctrl(&ethqos->pdev->dev);
	if (ret) {
		ETHQOSERR("ethqos_init_pinctrl failed");
		return ret;
	}

	ret = setup_gpio_input_common(&ethqos->pdev->dev,
				      "qcom,phy-intr-redirect",
+6 −6
Original line number Diff line number Diff line
@@ -37,10 +37,10 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)

	if (nopaged_len > BUF_SIZE_8KiB) {

		des2 = dma_map_single(priv->device, skb->data, bmax,
		des2 = dma_map_single(GET_MEM_PDEV_DEV, skb->data, bmax,
				      DMA_TO_DEVICE);
		desc->des2 = cpu_to_le32(des2);
		if (dma_mapping_error(priv->device, des2))
		if (dma_mapping_error(GET_MEM_PDEV_DEV, des2))
			return -1;

		tx_q->tx_skbuff_dma[entry].buf = des2;
@@ -58,10 +58,10 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)
		else
			desc = tx_q->dma_tx + entry;

		des2 = dma_map_single(priv->device, skb->data + bmax, len,
		des2 = dma_map_single(GET_MEM_PDEV_DEV, skb->data + bmax, len,
				      DMA_TO_DEVICE);
		desc->des2 = cpu_to_le32(des2);
		if (dma_mapping_error(priv->device, des2))
		if (dma_mapping_error(GET_MEM_PDEV_DEV, des2))
			return -1;
		tx_q->tx_skbuff_dma[entry].buf = des2;
		tx_q->tx_skbuff_dma[entry].len = len;
@@ -72,10 +72,10 @@ static int jumbo_frm(void *p, struct sk_buff *skb, int csum)
				STMMAC_RING_MODE, 1, !skb_is_nonlinear(skb),
				skb->len);
	} else {
		des2 = dma_map_single(priv->device, skb->data,
		des2 = dma_map_single(GET_MEM_PDEV_DEV, skb->data,
				      nopaged_len, DMA_TO_DEVICE);
		desc->des2 = cpu_to_le32(des2);
		if (dma_mapping_error(priv->device, des2))
		if (dma_mapping_error(GET_MEM_PDEV_DEV, des2))
			return -1;
		tx_q->tx_skbuff_dma[entry].buf = des2;
		tx_q->tx_skbuff_dma[entry].len = nopaged_len;
Loading