Commit 20d87a51 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'omap-for-v4.19/ti-sysc-v2-signed' of...

Merge tag 'omap-for-v4.19/ti-sysc-v2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/drivers

ti-sysc driver changes for v4.19 merge window

These changes add support for mcan controller found
on dra7 to probe it with only dts changes with no
need for legacy hwmod platform data. As it depends
on the related clock change, the clock change is
included here and acked by Stephen Boyd.

* tag 'omap-for-v4.19/ti-sysc-v2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  bus: ti-sysc: Add support for software reset
  bus: ti-sysc: Add support for using ti-sysc for MCAN on dra76x
  clk: ti: dra7: Add clkctrl clock data for the mcan clocks
  bus: ti-sysc: Use 2-factor allocator arguments
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents e541454a 596e7955
......@@ -36,6 +36,7 @@ Required standard properties:
"ti,sysc-omap-aes"
"ti,sysc-mcasp"
"ti,sysc-usb-host-fs"
"ti,sysc-dra7-mcan"
- reg shall have register areas implemented for the interconnect
target module in question such as revision, sysc and syss
......
......@@ -23,11 +23,14 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/iopoll.h>
#include <linux/platform_data/ti-sysc.h>
#include <dt-bindings/bus/ti-sysc.h>
#define MAX_MODULE_SOFTRESET_WAIT 10000
static const char * const reg_names[] = { "rev", "sysc", "syss", };
enum sysc_clocks {
......@@ -88,6 +91,11 @@ struct sysc {
struct delayed_work idle_work;
};
void sysc_write(struct sysc *ddata, int offset, u32 value)
{
writel_relaxed(value, ddata->module_va + offset);
}
static u32 sysc_read(struct sysc *ddata, int offset)
{
if (ddata->cfg.quirks & SYSC_QUIRK_16BIT) {
......@@ -169,9 +177,9 @@ static int sysc_get_clocks(struct sysc *ddata)
const char *name;
int nr_fck = 0, nr_ick = 0, i, error = 0;
ddata->clock_roles = devm_kzalloc(ddata->dev,
sizeof(*ddata->clock_roles) *
ddata->clock_roles = devm_kcalloc(ddata->dev,
SYSC_MAX_CLOCKS,
sizeof(*ddata->clock_roles),
GFP_KERNEL);
if (!ddata->clock_roles)
return -ENOMEM;
......@@ -200,8 +208,8 @@ static int sysc_get_clocks(struct sysc *ddata)
return -EINVAL;
}
ddata->clocks = devm_kzalloc(ddata->dev,
sizeof(*ddata->clocks) * ddata->nr_clocks,
ddata->clocks = devm_kcalloc(ddata->dev,
ddata->nr_clocks, sizeof(*ddata->clocks),
GFP_KERNEL);
if (!ddata->clocks)
return -ENOMEM;
......@@ -943,6 +951,36 @@ static void sysc_init_revision_quirks(struct sysc *ddata)
}
}
static int sysc_reset(struct sysc *ddata)
{
int offset = ddata->offsets[SYSC_SYSCONFIG];
int val;
if (ddata->legacy_mode || offset < 0 ||
ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
return 0;
/*
* Currently only support reset status in sysstatus.
* Warn and return error in all other cases
*/
if (!ddata->cfg.syss_mask) {
dev_err(ddata->dev, "No ti,syss-mask. Reset failed\n");
return -EINVAL;
}
val = sysc_read(ddata, offset);
val |= (0x1 << ddata->cap->regbits->srst_shift);
sysc_write(ddata, offset, val);
/* Poll on reset status */
offset = ddata->offsets[SYSC_SYSSTATUS];
return readl_poll_timeout(ddata->module_va + offset, val,
(val & ddata->cfg.syss_mask) == 0x0,
100, MAX_MODULE_SOFTRESET_WAIT);
}
/* At this point the module is configured enough to read the revision */
static int sysc_init_module(struct sysc *ddata)
{
......@@ -960,6 +998,14 @@ static int sysc_init_module(struct sysc *ddata)
return 0;
}
error = sysc_reset(ddata);
if (error) {
dev_err(ddata->dev, "Reset failed with %d\n", error);
pm_runtime_put_sync(ddata->dev);
return error;
}
ddata->revision = sysc_read_revision(ddata);
pm_runtime_put_sync(ddata->dev);
......@@ -1552,6 +1598,23 @@ static const struct sysc_capabilities sysc_omap4_usb_host_fs = {
.regbits = &sysc_regbits_omap4_usb_host_fs,
};
static const struct sysc_regbits sysc_regbits_dra7_mcan = {
.dmadisable_shift = -ENODEV,
.midle_shift = -ENODEV,
.sidle_shift = -ENODEV,
.clkact_shift = -ENODEV,
.enwkup_shift = 4,
.srst_shift = 0,
.emufree_shift = -ENODEV,
.autoidle_shift = -ENODEV,
};
static const struct sysc_capabilities sysc_dra7_mcan = {
.type = TI_SYSC_DRA7_MCAN,
.sysc_mask = SYSC_DRA7_MCAN_ENAWAKEUP | SYSC_OMAP4_SOFTRESET,
.regbits = &sysc_regbits_dra7_mcan,
};
static int sysc_init_pdata(struct sysc *ddata)
{
struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
......@@ -1743,6 +1806,7 @@ static const struct of_device_id sysc_match[] = {
{ .compatible = "ti,sysc-mcasp", .data = &sysc_omap4_mcasp, },
{ .compatible = "ti,sysc-usb-host-fs",
.data = &sysc_omap4_usb_host_fs, },
{ .compatible = "ti,sysc-dra7-mcan", .data = &sysc_dra7_mcan, },
{ },
};
MODULE_DEVICE_TABLE(of, sysc_match);
......
......@@ -708,6 +708,7 @@ static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initcons
{ DRA7_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
{ DRA7_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0060:24" },
{ DRA7_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0068:24" },
{ DRA7_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk"},
{ 0 },
};
......
......@@ -15,6 +15,8 @@
/* SmartReflex sysc found on 36xx and later */
#define SYSC_OMAP3_SR_ENAWAKEUP (1 << 26)
#define SYSC_DRA7_MCAN_ENAWAKEUP (1 << 4)
/* SYSCONFIG STANDBYMODE/MIDLEMODE/SIDLEMODE supported by hardware */
#define SYSC_IDLE_FORCE 0
#define SYSC_IDLE_NO 1
......
......@@ -168,5 +168,6 @@
#define DRA7_COUNTER_32K_CLKCTRL DRA7_CLKCTRL_INDEX(0x50)
#define DRA7_UART10_CLKCTRL DRA7_CLKCTRL_INDEX(0x80)
#define DRA7_DCAN1_CLKCTRL DRA7_CLKCTRL_INDEX(0x88)
#define DRA7_ADC_CLKCTRL DRA7_CLKCTRL_INDEX(0xa0)
#endif
......@@ -14,6 +14,7 @@ enum ti_sysc_module_type {
TI_SYSC_OMAP4_SR,
TI_SYSC_OMAP4_MCASP,
TI_SYSC_OMAP4_USB_HOST_FS,
TI_SYSC_DRA7_MCAN,
};
struct ti_sysc_cookie {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment