aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/bus/ti-sysc.c129
-rw-r--r--include/linux/platform_data/ti-sysc.h3
2 files changed, 127 insertions, 5 deletions
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
index a366ae548ec9..e6deabd8305d 100644
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -71,6 +71,9 @@ static const char * const clock_names[SYSC_MAX_CLOCKS] = {
71 * @name: name if available 71 * @name: name if available
72 * @revision: interconnect target module revision 72 * @revision: interconnect target module revision
73 * @needs_resume: runtime resume needed on resume from suspend 73 * @needs_resume: runtime resume needed on resume from suspend
74 * @clk_enable_quirk: module specific clock enable quirk
75 * @clk_disable_quirk: module specific clock disable quirk
76 * @reset_done_quirk: module specific reset done quirk
74 */ 77 */
75struct sysc { 78struct sysc {
76 struct device *dev; 79 struct device *dev;
@@ -94,6 +97,9 @@ struct sysc {
94 unsigned int child_needs_resume:1; 97 unsigned int child_needs_resume:1;
95 unsigned int disable_on_idle:1; 98 unsigned int disable_on_idle:1;
96 struct delayed_work idle_work; 99 struct delayed_work idle_work;
100 void (*clk_enable_quirk)(struct sysc *sysc);
101 void (*clk_disable_quirk)(struct sysc *sysc);
102 void (*reset_done_quirk)(struct sysc *sysc);
97}; 103};
98 104
99static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np, 105static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
@@ -760,8 +766,11 @@ static int sysc_ioremap(struct sysc *ddata)
760 ddata->offsets[SYSC_SYSCONFIG], 766 ddata->offsets[SYSC_SYSCONFIG],
761 ddata->offsets[SYSC_SYSSTATUS]); 767 ddata->offsets[SYSC_SYSSTATUS]);
762 768
769 if (size < SZ_1K)
770 size = SZ_1K;
771
763 if ((size + sizeof(u32)) > ddata->module_size) 772 if ((size + sizeof(u32)) > ddata->module_size)
764 return -EINVAL; 773 size = ddata->module_size;
765 } 774 }
766 775
767 ddata->module_va = devm_ioremap(ddata->dev, 776 ddata->module_va = devm_ioremap(ddata->dev,
@@ -1234,6 +1243,22 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
1234 SYSC_QUIRK_EXT_OPT_CLOCK | SYSC_QUIRK_NO_RESET_ON_INIT | 1243 SYSC_QUIRK_EXT_OPT_CLOCK | SYSC_QUIRK_NO_RESET_ON_INIT |
1235 SYSC_QUIRK_SWSUP_SIDLE), 1244 SYSC_QUIRK_SWSUP_SIDLE),
1236 1245
1246 /* Quirks that need to be set based on detected module */
1247 SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff,
1248 SYSC_MODULE_QUIRK_HDQ1W),
1249 SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff,
1250 SYSC_MODULE_QUIRK_HDQ1W),
1251 SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000036, 0x000000ff,
1252 SYSC_MODULE_QUIRK_I2C),
1253 SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x0000003c, 0x000000ff,
1254 SYSC_MODULE_QUIRK_I2C),
1255 SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000040, 0x000000ff,
1256 SYSC_MODULE_QUIRK_I2C),
1257 SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0,
1258 SYSC_MODULE_QUIRK_I2C),
1259 SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0,
1260 SYSC_MODULE_QUIRK_WDT),
1261
1237#ifdef DEBUG 1262#ifdef DEBUG
1238 SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0), 1263 SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0),
1239 SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0), 1264 SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0),
@@ -1247,11 +1272,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
1247 SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0), 1272 SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0),
1248 SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0), 1273 SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0),
1249 SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0), 1274 SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0),
1250 SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, 0),
1251 SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff, 0),
1252 SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0), 1275 SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0),
1253 SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0), 1276 SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0),
1254 SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0, 0),
1255 SYSC_QUIRK("lcdc", 0, 0, 0x54, -1, 0x4f201000, 0xffffffff, 0), 1277 SYSC_QUIRK("lcdc", 0, 0, 0x54, -1, 0x4f201000, 0xffffffff, 0),
1256 SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44306302, 0xffffffff, 0), 1278 SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44306302, 0xffffffff, 0),
1257 SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44307b02, 0xffffffff, 0), 1279 SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44307b02, 0xffffffff, 0),
@@ -1287,7 +1309,6 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
1287 SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0), 1309 SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0),
1288 SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050, 1310 SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
1289 0xffffffff, 0), 1311 0xffffffff, 0),
1290 SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, 0),
1291 SYSC_QUIRK("vfpe", 0, 0, 0x104, -1, 0x4d001200, 0xffffffff, 0), 1312 SYSC_QUIRK("vfpe", 0, 0, 0x104, -1, 0x4d001200, 0xffffffff, 0),
1292#endif 1313#endif
1293}; 1314};
@@ -1360,6 +1381,94 @@ static void sysc_init_revision_quirks(struct sysc *ddata)
1360 } 1381 }
1361} 1382}
1362 1383
1384/* 1-wire needs module's internal clocks enabled for reset */
1385static void sysc_clk_enable_quirk_hdq1w(struct sysc *ddata)
1386{
1387 int offset = 0x0c; /* HDQ_CTRL_STATUS */
1388 u16 val;
1389
1390 val = sysc_read(ddata, offset);
1391 val |= BIT(5);
1392 sysc_write(ddata, offset, val);
1393}
1394
1395/* I2C needs extra enable bit toggling for reset */
1396static void sysc_clk_quirk_i2c(struct sysc *ddata, bool enable)
1397{
1398 int offset;
1399 u16 val;
1400
1401 /* I2C_CON, omap2/3 is different from omap4 and later */
1402 if ((ddata->revision & 0xffffff00) == 0x001f0000)
1403 offset = 0x24;
1404 else
1405 offset = 0xa4;
1406
1407 /* I2C_EN */
1408 val = sysc_read(ddata, offset);
1409 if (enable)
1410 val |= BIT(15);
1411 else
1412 val &= ~BIT(15);
1413 sysc_write(ddata, offset, val);
1414}
1415
1416static void sysc_clk_enable_quirk_i2c(struct sysc *ddata)
1417{
1418 sysc_clk_quirk_i2c(ddata, true);
1419}
1420
1421static void sysc_clk_disable_quirk_i2c(struct sysc *ddata)
1422{
1423 sysc_clk_quirk_i2c(ddata, false);
1424}
1425
1426/* Watchdog timer needs a disable sequence after reset */
1427static void sysc_reset_done_quirk_wdt(struct sysc *ddata)
1428{
1429 int wps, spr, error;
1430 u32 val;
1431
1432 wps = 0x34;
1433 spr = 0x48;
1434
1435 sysc_write(ddata, spr, 0xaaaa);
1436 error = readl_poll_timeout(ddata->module_va + wps, val,
1437 !(val & 0x10), 100,
1438 MAX_MODULE_SOFTRESET_WAIT);
1439 if (error)
1440 dev_warn(ddata->dev, "wdt disable spr failed\n");
1441
1442 sysc_write(ddata, wps, 0x5555);
1443 error = readl_poll_timeout(ddata->module_va + wps, val,
1444 !(val & 0x10), 100,
1445 MAX_MODULE_SOFTRESET_WAIT);
1446 if (error)
1447 dev_warn(ddata->dev, "wdt disable wps failed\n");
1448}
1449
1450static void sysc_init_module_quirks(struct sysc *ddata)
1451{
1452 if (ddata->legacy_mode || !ddata->name)
1453 return;
1454
1455 if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_HDQ1W) {
1456 ddata->clk_enable_quirk = sysc_clk_enable_quirk_hdq1w;
1457
1458 return;
1459 }
1460
1461 if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) {
1462 ddata->clk_enable_quirk = sysc_clk_enable_quirk_i2c;
1463 ddata->clk_disable_quirk = sysc_clk_disable_quirk_i2c;
1464
1465 return;
1466 }
1467
1468 if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_WDT)
1469 ddata->reset_done_quirk = sysc_reset_done_quirk_wdt;
1470}
1471
1363static int sysc_clockdomain_init(struct sysc *ddata) 1472static int sysc_clockdomain_init(struct sysc *ddata)
1364{ 1473{
1365 struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev); 1474 struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
@@ -1468,10 +1577,16 @@ static int sysc_reset(struct sysc *ddata)
1468 else 1577 else
1469 syss_done = ddata->cfg.syss_mask; 1578 syss_done = ddata->cfg.syss_mask;
1470 1579
1580 if (ddata->clk_disable_quirk)
1581 ddata->clk_disable_quirk(ddata);
1582
1471 sysc_val = sysc_read_sysconfig(ddata); 1583 sysc_val = sysc_read_sysconfig(ddata);
1472 sysc_val |= sysc_mask; 1584 sysc_val |= sysc_mask;
1473 sysc_write(ddata, sysc_offset, sysc_val); 1585 sysc_write(ddata, sysc_offset, sysc_val);
1474 1586
1587 if (ddata->clk_enable_quirk)
1588 ddata->clk_enable_quirk(ddata);
1589
1475 /* Poll on reset status */ 1590 /* Poll on reset status */
1476 if (syss_offset >= 0) { 1591 if (syss_offset >= 0) {
1477 error = readx_poll_timeout(sysc_read_sysstatus, ddata, rstval, 1592 error = readx_poll_timeout(sysc_read_sysstatus, ddata, rstval,
@@ -1485,6 +1600,9 @@ static int sysc_reset(struct sysc *ddata)
1485 100, MAX_MODULE_SOFTRESET_WAIT); 1600 100, MAX_MODULE_SOFTRESET_WAIT);
1486 } 1601 }
1487 1602
1603 if (ddata->reset_done_quirk)
1604 ddata->reset_done_quirk(ddata);
1605
1488 return error; 1606 return error;
1489} 1607}
1490 1608
@@ -1531,6 +1649,7 @@ static int sysc_init_module(struct sysc *ddata)
1531 1649
1532 ddata->revision = sysc_read_revision(ddata); 1650 ddata->revision = sysc_read_revision(ddata);
1533 sysc_init_revision_quirks(ddata); 1651 sysc_init_revision_quirks(ddata);
1652 sysc_init_module_quirks(ddata);
1534 1653
1535 if (ddata->legacy_mode) { 1654 if (ddata->legacy_mode) {
1536 error = sysc_legacy_init(ddata); 1655 error = sysc_legacy_init(ddata);
diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h
index 8822e99ff813..0c587d4fc718 100644
--- a/include/linux/platform_data/ti-sysc.h
+++ b/include/linux/platform_data/ti-sysc.h
@@ -47,6 +47,9 @@ struct sysc_regbits {
47 s8 emufree_shift; 47 s8 emufree_shift;
48}; 48};
49 49
50#define SYSC_MODULE_QUIRK_HDQ1W BIT(17)
51#define SYSC_MODULE_QUIRK_I2C BIT(16)
52#define SYSC_MODULE_QUIRK_WDT BIT(15)
50#define SYSS_QUIRK_RESETDONE_INVERTED BIT(14) 53#define SYSS_QUIRK_RESETDONE_INVERTED BIT(14)
51#define SYSC_QUIRK_SWSUP_MSTANDBY BIT(13) 54#define SYSC_QUIRK_SWSUP_MSTANDBY BIT(13)
52#define SYSC_QUIRK_SWSUP_SIDLE_ACT BIT(12) 55#define SYSC_QUIRK_SWSUP_SIDLE_ACT BIT(12)