Driver changes for omaps for genpd support for v5.13

In order to move omap4/5 and dra7 to probe with devicetree data and genpd,
 we need to patch the related drivers to prepare.
 
 These are mostly ti-sysc interconnect target module driver changes and soc
 init changes. However, there are minor changes to other drivers too. There
 are changes for pci-dra7xx probe, omap-prm idle configuration, and a omap5
 clock change:
 
 - ti-sysc needs iorange check improved when the interconnect target module
   has no control registers listed
 
 - ti-sysc needs to probe l4_wkup and l4_cfg interconnects first to avoid
   issues with missing resources and unnecessary deferred probe
 
 - ti-sysc debug option can now detect more devices
 
 - ti-sysc now warns if an old incomplete devicetree data is found as we
   now rely on it being complete for am3 and 4
 
 - soc init code needs to check for prcm and prm nodes for omap4/5 and
   dra7
 
 - omap-prm driver needs to enable autoidle retention support for omap4
 
 - omap5 clocks are missing gpmc and ocmc clock registers
 
 - pci-dra7xx now needs to use builtin_platform_driver instead of using
   builtin_platform_driver_probe for deferred probe to work
 
 There are also few minor non-urgent fixes:
 
 - soc init code pdata_quirks_init_clocks should be static
 
 - ti-sysc has few unneeded semiconon typos
 
 - ti-sysc can use kzalloc instead of kcalloc for a single element
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEkgNvrZJU/QSQYIcQG9Q+yVyrpXMFAmBhemURHHRvbnlAYXRv
 bWlkZS5jb20ACgkQG9Q+yVyrpXPieBAA00Cpfk0s+vC4KASrq8pb2T9y14GOOwRe
 f8z9p8CDBhDtuhdJSVq//gkv3kIxUDfEN5LkOpsUWoGvbidiX6JlWcSvsA/27paV
 fzKl4xEqlqOkrZ38qGlJIKXBEvEW8yTaWXpkNnv9v83+kl3keU6Herx0RzqlCJCd
 iF7/CvKhOh0IyuaDHLjE1M+KVnBh1aKSfeLXKOQakOgdeZC+dE6eyaY700iBbBmu
 Za/Ug4XoZUJ8bn6i3S6wa3p3MhUOlXGoW4zFCDC2GeK+Mqf2iyIEbotMDsNSncL2
 uPa/CIiu4FjFuhlwLh23nXciGndEWYR7DCZRntwGs5ZJNNXqFYaE3hNKJ/WsVNj9
 lx5M5CqY5mFjJ7WMySPp7YCi3D2W7fyEcnwUl4Ptah1inYuNgF31CXWy/Xy6VbJN
 yMDFM3EBlP3DXG7t8I9O4lr8H9PzQNvJ7OdFaNLZq9Qp+wzRZ4uW2jVpriB9pSP+
 TmOmjlZI3emY852KnWeTqerERB/THmpb7J71Md9KbztXIT5LSBknzmqGW57ie6EC
 EM3ZktjV82dYzv7/OGEJVcctSVSB50tNZoCXwnVpzXagSOZYh9IiRMjPd/SMmJgt
 BZINrpsQpsLk6w5zVWF0zfhG7DFDJ862tyGqJZzAJhlCEC+av0Xs90+jl0X0n8uE
 fFq1RUxR7rU=
 =lf62
 -----END PGP SIGNATURE-----

Merge tag 'omap-for-v5.13/ti-sysc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/drivers

Driver changes for omaps for genpd support for v5.13

In order to move omap4/5 and dra7 to probe with devicetree data and genpd,
we need to patch the related drivers to prepare.

These are mostly ti-sysc interconnect target module driver changes and soc
init changes. However, there are minor changes to other drivers too. There
are changes for pci-dra7xx probe, omap-prm idle configuration, and a omap5
clock change:

- ti-sysc needs iorange check improved when the interconnect target module
  has no control registers listed

- ti-sysc needs to probe l4_wkup and l4_cfg interconnects first to avoid
  issues with missing resources and unnecessary deferred probe

- ti-sysc debug option can now detect more devices

- ti-sysc now warns if an old incomplete devicetree data is found as we
  now rely on it being complete for am3 and 4

- soc init code needs to check for prcm and prm nodes for omap4/5 and
  dra7

- omap-prm driver needs to enable autoidle retention support for omap4

- omap5 clocks are missing gpmc and ocmc clock registers

- pci-dra7xx now needs to use builtin_platform_driver instead of using
  builtin_platform_driver_probe for deferred probe to work

There are also few minor non-urgent fixes:

- soc init code pdata_quirks_init_clocks should be static

- ti-sysc has few unneeded semiconon typos

- ti-sysc can use kzalloc instead of kcalloc for a single element

* tag 'omap-for-v5.13/ti-sysc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  bus: ti-sysc: Use kzalloc for allocating only one thing
  bus: ti-sysc: remove unneeded semicolon
  ARM: OMAP2+: Make symbol 'pdata_quirks_init_clocks' static
  PCI: pci-dra7xx: Prepare for deferred probe with module_platform_driver
  clk: ti: omap5: Add missing gpmc and ocmc clkctrl
  soc: ti: omap-prm: Allow hardware supported retention when idle
  ARM: OMAP2+: Init both prm and prcm nodes early for clocks
  bus: ti-sysc: Check for old incomplete dtb
  bus: ti-sysc: Detect more modules for debugging
  bus: ti-sysc: Probe for l4_wkup and l4_cfg interconnect devices first
  bus: ti-sysc: Fix initializing module_pa for modules without sysc register
  ARM: dts: Fix moving mmc devices with aliases for omap4 & 5
  ARM: dts: Drop duplicate sha2md5_fck to fix clk_disable race
  soc: ti: omap-prm: Fix occasional abort on reset deassert for dra7 iva
  bus: ti-sysc: Fix warning on unbind if reset is not deasserted
  ARM: OMAP2+: Fix smartreflex init regression after dropping legacy data
  soc: ti: omap-prm: Fix reboot issue with invalid pcie reset map for dra7
  ARM: dts: am33xx: add aliases for mmc interfaces
  bus: omap_l3_noc: mark l3 irqs as IRQF_NO_THREAD

Link: https://lore.kernel.org/r/pull-1617004205-537424@atomide.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2021-04-01 20:59:59 +02:00
commit 1d79dca631
12 changed files with 204 additions and 54 deletions

View file

@ -40,6 +40,9 @@ aliases {
ethernet1 = &cpsw_emac1;
spi0 = &spi0;
spi1 = &spi1;
mmc0 = &mmc1;
mmc1 = &mmc2;
mmc2 = &mmc3;
};
cpus {

View file

@ -22,6 +22,11 @@ aliases {
i2c1 = &i2c2;
i2c2 = &i2c3;
i2c3 = &i2c4;
mmc0 = &mmc1;
mmc1 = &mmc2;
mmc2 = &mmc3;
mmc3 = &mmc4;
mmc4 = &mmc5;
serial0 = &uart1;
serial1 = &uart2;
serial2 = &uart3;

View file

@ -770,14 +770,6 @@ per_abe_nc_fclk: per_abe_nc_fclk@108 {
ti,max-div = <2>;
};
sha2md5_fck: sha2md5_fck@15c8 {
#clock-cells = <0>;
compatible = "ti,gate-clock";
clocks = <&l3_div_ck>;
ti,bit-shift = <1>;
reg = <0x15c8>;
};
usb_phy_cm_clk32k: usb_phy_cm_clk32k@640 {
#clock-cells = <0>;
compatible = "ti,gate-clock";

View file

@ -25,6 +25,11 @@ aliases {
i2c2 = &i2c3;
i2c3 = &i2c4;
i2c4 = &i2c5;
mmc0 = &mmc1;
mmc1 = &mmc2;
mmc2 = &mmc3;
mmc3 = &mmc4;
mmc4 = &mmc5;
serial0 = &uart1;
serial1 = &uart2;
serial2 = &uart3;

View file

@ -569,10 +569,29 @@ static void pdata_quirks_check(struct pdata_init *quirks)
}
}
void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
static const char * const pdata_quirks_init_nodes[] = {
"prcm",
"prm",
};
static void __init
pdata_quirks_init_clocks(const struct of_device_id *omap_dt_match_table)
{
struct device_node *np;
int i;
for (i = 0; i < ARRAY_SIZE(pdata_quirks_init_nodes); i++) {
np = of_find_node_by_name(NULL, pdata_quirks_init_nodes[i]);
if (!np)
continue;
of_platform_populate(np, omap_dt_match_table,
omap_auxdata_lookup, NULL);
}
}
void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
{
/*
* We still need this for omap2420 and omap3 PM to work, others are
* using drivers/misc/sram.c already.
@ -585,13 +604,7 @@ void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
omap3_mcbsp_init();
pdata_quirks_check(auxdata_quirks);
/* Populate always-on PRCM in l4_wkup to probe l4_wkup */
np = of_find_node_by_name(NULL, "prcm");
if (!np)
np = of_find_node_by_name(NULL, "prm");
if (np)
of_platform_populate(np, omap_dt_match_table,
omap_auxdata_lookup, NULL);
pdata_quirks_init_clocks(omap_dt_match_table);
of_platform_populate(NULL, omap_dt_match_table,
omap_auxdata_lookup, NULL);

View file

@ -88,34 +88,26 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
extern struct omap_sr_data omap_sr_pdata[];
static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
static int __init sr_init_by_name(const char *name, const char *voltdm)
{
struct omap_sr_data *sr_data = NULL;
struct omap_volt_data *volt_data;
struct omap_smartreflex_dev_attr *sr_dev_attr;
static int i;
if (!strncmp(oh->name, "smartreflex_mpu_iva", 20) ||
!strncmp(oh->name, "smartreflex_mpu", 16))
if (!strncmp(name, "smartreflex_mpu_iva", 20) ||
!strncmp(name, "smartreflex_mpu", 16))
sr_data = &omap_sr_pdata[OMAP_SR_MPU];
else if (!strncmp(oh->name, "smartreflex_core", 17))
else if (!strncmp(name, "smartreflex_core", 17))
sr_data = &omap_sr_pdata[OMAP_SR_CORE];
else if (!strncmp(oh->name, "smartreflex_iva", 16))
else if (!strncmp(name, "smartreflex_iva", 16))
sr_data = &omap_sr_pdata[OMAP_SR_IVA];
if (!sr_data) {
pr_err("%s: Unknown instance %s\n", __func__, oh->name);
pr_err("%s: Unknown instance %s\n", __func__, name);
return -EINVAL;
}
sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
pr_err("%s: No voltage domain specified for %s. Cannot initialize\n",
__func__, oh->name);
goto exit;
}
sr_data->name = oh->name;
sr_data->name = name;
if (cpu_is_omap343x())
sr_data->ip_type = 1;
else
@ -136,10 +128,10 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
}
}
sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
sr_data->voltdm = voltdm_lookup(voltdm);
if (!sr_data->voltdm) {
pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
__func__, sr_dev_attr->sensor_voltdm_name);
__func__, voltdm);
goto exit;
}
@ -160,6 +152,20 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
return 0;
}
static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
{
struct omap_smartreflex_dev_attr *sr_dev_attr;
sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
pr_err("%s: No voltage domain specified for %s. Cannot initialize\n",
__func__, oh->name);
return 0;
}
return sr_init_by_name(oh->name, sr_dev_attr->sensor_voltdm_name);
}
/*
* API to be called from board files to enable smartreflex
* autocompensation at init.
@ -169,7 +175,42 @@ void __init omap_enable_smartreflex_on_init(void)
sr_enable_on_init = true;
}
static const char * const omap4_sr_instances[] = {
"mpu",
"iva",
"core",
};
static const char * const dra7_sr_instances[] = {
"mpu",
"core",
};
int __init omap_devinit_smartreflex(void)
{
const char * const *sr_inst;
int i, nr_sr = 0;
if (soc_is_omap44xx()) {
sr_inst = omap4_sr_instances;
nr_sr = ARRAY_SIZE(omap4_sr_instances);
} else if (soc_is_dra7xx()) {
sr_inst = dra7_sr_instances;
nr_sr = ARRAY_SIZE(dra7_sr_instances);
}
if (nr_sr) {
const char *name, *voltdm;
for (i = 0; i < nr_sr; i++) {
name = kasprintf(GFP_KERNEL, "smartreflex_%s", sr_inst[i]);
voltdm = sr_inst[i];
sr_init_by_name(name, voltdm);
}
return 0;
}
return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL);
}

View file

@ -285,7 +285,7 @@ static int omap_l3_probe(struct platform_device *pdev)
*/
l3->debug_irq = platform_get_irq(pdev, 0);
ret = devm_request_irq(l3->dev, l3->debug_irq, l3_interrupt_handler,
0x0, "l3-dbg-irq", l3);
IRQF_NO_THREAD, "l3-dbg-irq", l3);
if (ret) {
dev_err(l3->dev, "request_irq failed for %d\n",
l3->debug_irq);
@ -294,7 +294,7 @@ static int omap_l3_probe(struct platform_device *pdev)
l3->app_irq = platform_get_irq(pdev, 1);
ret = devm_request_irq(l3->dev, l3->app_irq, l3_interrupt_handler,
0x0, "l3-app-irq", l3);
IRQF_NO_THREAD, "l3-app-irq", l3);
if (ret)
dev_err(l3->dev, "request_irq failed for %d\n", l3->app_irq);

View file

@ -288,7 +288,7 @@ static int sysc_add_named_clock_from_child(struct sysc *ddata,
* limit for clk_get(). If cl ever needs to be freed, it should be done
* with clkdev_drop().
*/
cl = kcalloc(1, sizeof(*cl), GFP_KERNEL);
cl = kzalloc(sizeof(*cl), GFP_KERNEL);
if (!cl)
return -ENOMEM;
@ -635,6 +635,51 @@ static int sysc_parse_and_check_child_range(struct sysc *ddata)
return 0;
}
/* Interconnect instances to probe before l4_per instances */
static struct resource early_bus_ranges[] = {
/* am3/4 l4_wkup */
{ .start = 0x44c00000, .end = 0x44c00000 + 0x300000, },
/* omap4/5 and dra7 l4_cfg */
{ .start = 0x4a000000, .end = 0x4a000000 + 0x300000, },
/* omap4 l4_wkup */
{ .start = 0x4a300000, .end = 0x4a300000 + 0x30000, },
/* omap5 and dra7 l4_wkup without dra7 dcan segment */
{ .start = 0x4ae00000, .end = 0x4ae00000 + 0x30000, },
};
static atomic_t sysc_defer = ATOMIC_INIT(10);
/**
* sysc_defer_non_critical - defer non_critical interconnect probing
* @ddata: device driver data
*
* We want to probe l4_cfg and l4_wkup interconnect instances before any
* l4_per instances as l4_per instances depend on resources on l4_cfg and
* l4_wkup interconnects.
*/
static int sysc_defer_non_critical(struct sysc *ddata)
{
struct resource *res;
int i;
if (!atomic_read(&sysc_defer))
return 0;
for (i = 0; i < ARRAY_SIZE(early_bus_ranges); i++) {
res = &early_bus_ranges[i];
if (ddata->module_pa >= res->start &&
ddata->module_pa <= res->end) {
atomic_set(&sysc_defer, 0);
return 0;
}
}
atomic_dec_if_positive(&sysc_defer);
return -EPROBE_DEFER;
}
static struct device_node *stdout_path;
static void sysc_init_stdout_path(struct sysc *ddata)
@ -856,15 +901,19 @@ static int sysc_map_and_check_registers(struct sysc *ddata)
struct device_node *np = ddata->dev->of_node;
int error;
if (!of_get_property(np, "reg", NULL))
return 0;
error = sysc_parse_and_check_child_range(ddata);
if (error)
return error;
error = sysc_defer_non_critical(ddata);
if (error)
return error;
sysc_check_children(ddata);
if (!of_get_property(np, "reg", NULL))
return 0;
error = sysc_parse_registers(ddata);
if (error)
return error;
@ -1447,12 +1496,16 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
SYSC_QUIRK("dwc3", 0, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, 0),
SYSC_QUIRK("d2d", 0x4a0b6000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
SYSC_QUIRK("d2d", 0x4a0cd000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
SYSC_QUIRK("elm", 0x48080000, 0, 0x10, 0x14, 0x00000020, 0xffffffff, 0),
SYSC_QUIRK("emif", 0, 0, -ENODEV, -ENODEV, 0x40441403, 0xffff0fff, 0),
SYSC_QUIRK("emif", 0, 0, -ENODEV, -ENODEV, 0x50440500, 0xffffffff, 0),
SYSC_QUIRK("epwmss", 0, 0, 0x4, -ENODEV, 0x47400001, 0xffffffff, 0),
SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -ENODEV, 0, 0, 0),
SYSC_QUIRK("gpu", 0, 0xfe00, 0xfe10, -ENODEV, 0x40000000 , 0xffffffff, 0),
SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50031d00, 0xffffffff, 0),
SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0),
SYSC_QUIRK("iss", 0, 0, 0x10, -ENODEV, 0x40000101, 0xffffffff, 0),
SYSC_QUIRK("keypad", 0x4a31c000, 0, 0x10, 0x14, 0x00000020, 0xffffffff, 0),
SYSC_QUIRK("mcasp", 0, 0, 0x4, -ENODEV, 0x44306302, 0xffffffff, 0),
SYSC_QUIRK("mcasp", 0, 0, 0x4, -ENODEV, 0x44307b02, 0xffffffff, 0),
SYSC_QUIRK("mcbsp", 0, -ENODEV, 0x8c, -ENODEV, 0, 0, 0),
@ -1464,11 +1517,14 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
SYSC_QUIRK("ocp2scp", 0, 0, -ENODEV, -ENODEV, 0x50060007, 0xffffffff, 0),
SYSC_QUIRK("padconf", 0, 0, 0x10, -ENODEV, 0x4fff0800, 0xffffffff, 0),
SYSC_QUIRK("padconf", 0, 0, -ENODEV, -ENODEV, 0x40001100, 0xffffffff, 0),
SYSC_QUIRK("pcie", 0x51000000, -ENODEV, -ENODEV, -ENODEV, 0, 0, 0),
SYSC_QUIRK("pcie", 0x51800000, -ENODEV, -ENODEV, -ENODEV, 0, 0, 0),
SYSC_QUIRK("prcm", 0, 0, -ENODEV, -ENODEV, 0x40000100, 0xffffffff, 0),
SYSC_QUIRK("prcm", 0, 0, -ENODEV, -ENODEV, 0x00004102, 0xffffffff, 0),
SYSC_QUIRK("prcm", 0, 0, -ENODEV, -ENODEV, 0x40000400, 0xffffffff, 0),
SYSC_QUIRK("rfbi", 0x4832a800, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
SYSC_QUIRK("rfbi", 0x58002000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0),
SYSC_QUIRK("sata", 0, 0xfc, 0x1100, -ENODEV, 0x5e412000, 0xffffffff, 0),
SYSC_QUIRK("scm", 0, 0, 0x10, -ENODEV, 0x40000900, 0xffffffff, 0),
SYSC_QUIRK("scm", 0, 0, -ENODEV, -ENODEV, 0x4e8b0100, 0xffffffff, 0),
SYSC_QUIRK("scm", 0, 0, -ENODEV, -ENODEV, 0x4f000100, 0xffffffff, 0),
@ -1592,7 +1648,7 @@ static u32 sysc_quirk_dispc(struct sysc *ddata, int dispc_offset,
case SOC_UNKNOWN:
default:
return 0;
};
}
/* Remap the whole module range to be able to reset dispc outputs */
devm_iounmap(ddata->dev, ddata->module_va);
@ -2802,6 +2858,7 @@ static int sysc_init_soc(struct sysc *ddata)
const struct soc_device_attribute *match;
struct ti_sysc_platform_data *pdata;
unsigned long features = 0;
struct device_node *np;
if (sysc_soc)
return 0;
@ -2822,6 +2879,21 @@ static int sysc_init_soc(struct sysc *ddata)
if (match && match->data)
sysc_soc->soc = (int)match->data;
/*
* Check and warn about possible old incomplete dtb. We now want to see
* simple-pm-bus instead of simple-bus in the dtb for genpd using SoCs.
*/
switch (sysc_soc->soc) {
case SOC_AM3:
case SOC_AM4:
np = of_find_node_by_path("/ocp");
WARN_ONCE(np && of_device_is_compatible(np, "simple-bus"),
"ti-sysc: Incomplete old dtb, please update\n");
break;
default:
break;
}
/* Ignore devices that are not available on HS and EMU SoCs */
if (!sysc_soc->general_purpose) {
switch (sysc_soc->soc) {
@ -2830,7 +2902,7 @@ static int sysc_init_soc(struct sysc *ddata)
break;
default:
break;
};
}
}
match = soc_device_match(sysc_soc_feat_match);
@ -3053,7 +3125,9 @@ static int sysc_remove(struct platform_device *pdev)
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
reset_control_assert(ddata->rsts);
if (!reset_control_status(ddata->rsts))
reset_control_assert(ddata->rsts);
unprepare:
sysc_unprepare(ddata);

View file

@ -156,6 +156,8 @@ static const struct omap_clkctrl_reg_data omap5_l3main1_clkctrl_regs[] __initcon
static const struct omap_clkctrl_reg_data omap5_l3main2_clkctrl_regs[] __initconst = {
{ OMAP5_L3_MAIN_2_CLKCTRL, NULL, 0, "l3_iclk_div" },
{ OMAP5_L3_MAIN_2_GPMC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
{ OMAP5_L3_MAIN_2_OCMC_RAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" },
{ 0 },
};

View file

@ -443,8 +443,8 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = {
.get_features = dra7xx_pcie_get_features,
};
static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
struct platform_device *pdev)
static int dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
struct platform_device *pdev)
{
int ret;
struct dw_pcie_ep *ep;
@ -472,8 +472,8 @@ static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
return 0;
}
static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
struct platform_device *pdev)
static int dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
struct platform_device *pdev)
{
int ret;
struct dw_pcie *pci = dra7xx->pci;
@ -682,7 +682,7 @@ static int dra7xx_pcie_configure_two_lane(struct device *dev,
return 0;
}
static int __init dra7xx_pcie_probe(struct platform_device *pdev)
static int dra7xx_pcie_probe(struct platform_device *pdev)
{
u32 reg;
int ret;
@ -938,6 +938,7 @@ static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
};
static struct platform_driver dra7xx_pcie_driver = {
.probe = dra7xx_pcie_probe,
.driver = {
.name = "dra7-pcie",
.of_match_table = of_dra7xx_pcie_match,
@ -946,4 +947,4 @@ static struct platform_driver dra7xx_pcie_driver = {
},
.shutdown = dra7xx_pcie_shutdown,
};
builtin_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe);
builtin_platform_driver(dra7xx_pcie_driver);

View file

@ -88,6 +88,7 @@ struct omap_reset_data {
#define OMAP_PRM_HAS_RSTCTRL BIT(0)
#define OMAP_PRM_HAS_RSTST BIT(1)
#define OMAP_PRM_HAS_NO_CLKDM BIT(2)
#define OMAP_PRM_RET_WHEN_IDLE BIT(3)
#define OMAP_PRM_HAS_RESETS (OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_RSTST)
@ -174,7 +175,8 @@ static const struct omap_prm_data omap4_prm_data[] = {
.name = "core", .base = 0x4a306700,
.pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton,
.rstctrl = 0x210, .rstst = 0x214, .clkdm_name = "ducati",
.rstmap = rst_map_012
.rstmap = rst_map_012,
.flags = OMAP_PRM_RET_WHEN_IDLE,
},
{
.name = "ivahd", .base = 0x4a306f00,
@ -199,7 +201,8 @@ static const struct omap_prm_data omap4_prm_data[] = {
},
{
.name = "l4per", .base = 0x4a307400,
.pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton
.pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_reton,
.flags = OMAP_PRM_RET_WHEN_IDLE,
},
{
.name = "cefuse", .base = 0x4a307600,
@ -332,7 +335,7 @@ static const struct omap_prm_data dra7_prm_data[] = {
{
.name = "l3init", .base = 0x4ae07300,
.pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
.rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_012,
.rstctrl = 0x10, .rstst = 0x14, .rstmap = rst_map_01,
.clkdm_name = "pcie"
},
{
@ -517,7 +520,7 @@ static int omap_prm_domain_power_on(struct generic_pm_domain *domain)
{
struct omap_prm_domain *prmd;
int ret;
u32 v;
u32 v, mode;
prmd = genpd_to_prm_domain(domain);
if (!prmd->cap)
@ -530,7 +533,12 @@ static int omap_prm_domain_power_on(struct generic_pm_domain *domain)
else
v = readl_relaxed(prmd->prm->base + prmd->pwrstctrl);
writel_relaxed(v | OMAP_PRMD_ON_ACTIVE,
if (prmd->prm->data->flags & OMAP_PRM_RET_WHEN_IDLE)
mode = OMAP_PRMD_RETENTION;
else
mode = OMAP_PRMD_ON_ACTIVE;
writel_relaxed((v & ~PRM_POWERSTATE_MASK) | mode,
prmd->prm->base + prmd->pwrstctrl);
/* wait for the transition bit to get cleared */
@ -830,8 +838,12 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev,
reset->prm->data->name, id);
exit:
if (reset->clkdm)
if (reset->clkdm) {
/* At least dra7 iva needs a delay before clkdm idle */
if (has_rstst)
udelay(1);
pdata->clkdm_allow_idle(reset->clkdm);
}
return ret;
}

View file

@ -32,6 +32,8 @@
/* l3main2 clocks */
#define OMAP5_L3_MAIN_2_CLKCTRL OMAP5_CLKCTRL_INDEX(0x20)
#define OMAP5_L3_MAIN_2_GPMC_CLKCTRL OMAP5_CLKCTRL_INDEX(0x28)
#define OMAP5_L3_MAIN_2_OCMC_RAM_CLKCTRL OMAP5_CLKCTRL_INDEX(0x30)
/* ipu clocks */
#define OMAP5_MMU_IPU_CLKCTRL OMAP5_CLKCTRL_INDEX(0x20)