static void uniphier_fi2c_hw_init(struct uniphier_fi2c_priv *priv, u32 bus_speed, unsigned long clk_rate) { u32 tmp; tmp = readl(priv->membase + UNIPHIER_FI2C_CR); tmp |= UNIPHIER_FI2C_CR_MST; writel(tmp, priv->membase + UNIPHIER_FI2C_CR); uniphier_fi2c_reset(priv); tmp = clk_rate / bus_speed; writel(tmp, priv->membase + UNIPHIER_FI2C_CYC); writel(tmp / 2, priv->membase + UNIPHIER_FI2C_LCTL); writel(tmp / 2, priv->membase + UNIPHIER_FI2C_SSUT); writel(tmp / 16, priv->membase + UNIPHIER_FI2C_DSUT); uniphier_fi2c_prepare_operation(priv); }
static int uniphier_fi2c_clk_init(struct device *dev, struct uniphier_fi2c_priv *priv) { struct device_node *np = dev->of_node; unsigned long clk_rate; u32 bus_speed, clk_count; int ret; if (of_property_read_u32(np, "clock-frequency", &bus_speed)) bus_speed = UNIPHIER_FI2C_DEFAULT_SPEED; if (bus_speed > UNIPHIER_FI2C_MAX_SPEED) bus_speed = UNIPHIER_FI2C_MAX_SPEED; /* Get input clk rate through clk driver */ priv->clk = devm_clk_get(dev, NULL); if (IS_ERR(priv->clk)) { dev_err(dev, "failed to get clock\n"); return PTR_ERR(priv->clk); } ret = clk_prepare_enable(priv->clk); if (ret) return ret; clk_rate = clk_get_rate(priv->clk); uniphier_fi2c_reset(priv); clk_count = clk_rate / bus_speed; writel(clk_count, priv->membase + UNIPHIER_FI2C_CYC); writel(clk_count / 2, priv->membase + UNIPHIER_FI2C_LCTL); writel(clk_count / 2, priv->membase + UNIPHIER_FI2C_SSUT); writel(clk_count / 16, priv->membase + UNIPHIER_FI2C_DSUT); uniphier_fi2c_prepare_operation(priv); return 0; }
static void uniphier_fi2c_recover(struct uniphier_fi2c_priv *priv) { uniphier_fi2c_reset(priv); i2c_recover_bus(&priv->adap); }