Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions Documentation/devicetree/bindings/rtc/apple,smc-rtc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,36 @@ properties:
const: apple,smc-rtc

nvmem-cells:
minItems: 1
items:
- description:
RTC offset. By default a 48bit value, specified in 32768 (2^15) Hz
clock ticks. With apple,rtc-offset-seconds, a 64bit little-endian
count of whole seconds.
- description:
PMU alarm control byte, with the alarm enable, the monitor bit and
the latched alarm event.
- description:
PMU alarm compare value, a 32-bit count of whole seconds of the RTC
counter without the offset.
- description: PMU alarm mask byte.

nvmem-cell-names:
items:
- const: rtc_offset
oneOf:
- items:
- const: rtc_offset
- items:
- const: rtc_offset
- const: rtc_ctrl
- const: rtc_alarm
- const: rtc_alarm_mask

interrupts:
maxItems: 1
description:
The PMU's RTC alarm interrupt. Only used with the three alarm cells.

wakeup-source: true

apple,rtc-offset-seconds:
type: boolean
Expand Down
23 changes: 21 additions & 2 deletions arch/arm64/boot/dts/apple/t6030.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,8 @@
#size-cells = <0>;
interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 485 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;

Check warning on line 1063 in arch/arm64/boot/dts/apple/t6030.dtsi

View workflow job for this annotation

GitHub Actions / ci / device trees

dt-check style

[property-order] property 'interrupt-controller' out of canonical order (should sort before 'interrupts')
#interrupt-cells = <2>;

pmic1: pmic@b {
compatible = "apple,chapel-pmic", "apple,spmi-nvmem";
Expand All @@ -1070,10 +1072,22 @@
#address-cells = <1>;
#size-cells = <1>;

rtc_ctrl: rtc-ctrl@2000 {
reg = <0x2000 0x1>;
};

pm_setting: pm-setting@2001 {
reg = <0x2001 0x1>;
};

rtc_alarm: rtc-alarm@2008 {
reg = <0x2008 0x4>;
};

rtc_alarm_mask: rtc-alarm-mask@200e {
reg = <0x200e 0x1>;
};

rtc_offset: rtc-offset@2100 {
reg = <0x2100 0x6>;
};
Expand Down Expand Up @@ -1182,8 +1196,13 @@

rtc {
compatible = "apple,smc-rtc";
nvmem-cells = <&rtc_offset>;
nvmem-cell-names = "rtc_offset";
nvmem-cells = <&rtc_offset>, <&rtc_ctrl>, <&rtc_alarm>,
<&rtc_alarm_mask>;

Check warning on line 1200 in arch/arm64/boot/dts/apple/t6030.dtsi

View workflow job for this annotation

GitHub Actions / ci / device trees

dt-check style

[continuation-alignment] continuation should align to column 47 (under "<" or \")
nvmem-cell-names = "rtc_offset", "rtc_ctrl", "rtc_alarm",
"rtc_alarm_mask";

Check warning on line 1202 in arch/arm64/boot/dts/apple/t6030.dtsi

View workflow job for this annotation

GitHub Actions / ci / device trees

dt-check style

[continuation-alignment] continuation should align to column 52 (under "<" or \")
/* The PMIC's RTC alarm, peripheral interrupt 2 of nub-spmi0 */

Check warning on line 1203 in arch/arm64/boot/dts/apple/t6030.dtsi

View workflow job for this annotation

GitHub Actions / ci / device trees

dt-check style

[line-length] line exceeds 80 columns (95)
interrupts-extended = <&nub_spmi 2 IRQ_TYPE_EDGE_RISING>;

Check warning on line 1204 in arch/arm64/boot/dts/apple/t6030.dtsi

View workflow job for this annotation

GitHub Actions / ci / device trees

dt-check style

[property-order] property 'interrupts-extended' out of canonical order (should sort before 'nvmem-cell-names')
wakeup-source;
};
};

Expand Down Expand Up @@ -1520,7 +1539,7 @@
port02: pci@2,0 {
device_type = "pci";
reg = <0x1000 0x0 0x0 0x0 0x0>;
reset-gpios = <&pinctrl_ap 169 GPIO_ACTIVE_LOW>; // perst

Check warning on line 1542 in arch/arm64/boot/dts/apple/t6030.dtsi

View workflow job for this annotation

GitHub Actions / ci / device trees

dt-check style

[line-length] line exceeds 80 columns (89)

#address-cells = <3>;
#size-cells = <2>;
Expand All @@ -1547,7 +1566,7 @@
ranges;

interrupt-controller;
#interrupt-cells = <1>;

Check warning on line 1569 in arch/arm64/boot/dts/apple/t6030.dtsi

View workflow job for this annotation

GitHub Actions / ci / device trees

dt-check style

[property-order] property '#interrupt-cells' out of canonical order (should sort before 'interrupt-controller')

interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &port03 0 0 0 0>,
Expand Down Expand Up @@ -2063,7 +2082,7 @@

dwc3_2: usb@f02280000 {
compatible = "apple,t6030-dwc3", "apple,t8103-dwc3";
reg = <0xf 0x02280000 0x0 0xcd00>, <0xf 0x0228cd00 0x0 0x3200>;

Check warning on line 2085 in arch/arm64/boot/dts/apple/t6030.dtsi

View workflow job for this annotation

GitHub Actions / ci / device trees

dt-check style

[line-length] line exceeds 80 columns (87)
reg-names = "dwc3-core", "dwc3-apple";
interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 1203 IRQ_TYPE_LEVEL_HIGH>;
Expand Down
79 changes: 79 additions & 0 deletions drivers/pmdomain/apple/pmp-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,9 @@ struct apple_pmp_report_entry {
u32 id;
/* The PMP does not acknowledge this request (a started PMP only). */
bool no_ack;
/* Withdrawn for system sleep (apple,release-for-sleep), and now so. */
bool sleep_release;
bool released;
bool removed;
};

Expand Down Expand Up @@ -1368,6 +1371,80 @@ static int apple_pmp_report_entry_set_state(struct generic_pm_domain *genpd, boo
return ret;
}

/*
* System sleep. An external display processor's request keeps the PMP's
* external display state up while nothing is shown, about 0.25 W in
* suspend-to-idle on J514S. By the noirq phase every display processor has
* suspended, its displays off and its links released or idle: withdraw such a
* request if it is acknowledged, with one replacement write as macOS releases
* its display requests, and assert it again before the processors resume.
*/
static int apple_pmp_report_entry_sleep(struct apple_pmp_report_entry *ent, bool release)
{
struct apple_pmp_report *rep;
int ret = -ENODEV;

rcu_read_lock();
list_for_each_entry_rcu(rep, &apple_pmp_reports, list) {
if (rep->dev->of_node != ent->report_node)
continue;
if (release && (!(readq(rep->base + rep->offsets->status) & PMP_REPORT_READY) ||
!(readq(rep->base + rep->offsets->actual) & BIT_ULL(ent->id))))
ret = -EALREADY;
else
ret = apple_pmp_report_set_state(rep, ent->id, !release, ent->no_ack);
break;
}
rcu_read_unlock();
return ret;
}

static int apple_pmp_report_entry_suspend_noirq(struct device *dev)
{
struct apple_pmp_report_entry *ent = dev_get_drvdata(dev);
int ret;

if (!ent || !ent->sleep_release || READ_ONCE(ent->removed))
return 0;
ret = apple_pmp_report_entry_sleep(ent, true);
if (ret == -EALREADY)
return 0;
/* A withdrawal that was not acknowledged is asserted again all the same. */
if (ret)
dev_warn(dev, "request %u not withdrawn for sleep: %d\n", ent->id, ret);
ent->released = true;
return 0;
}

static int apple_pmp_report_entry_resume_noirq(struct device *dev)
{
struct apple_pmp_report_entry *ent = dev_get_drvdata(dev);
int ret, tries = 0;

if (!ent || !ent->released)
return 0;
ent->released = false;
/*
* Without the request the external display stays dark until reboot:
* write it again, three times at most, while the PMP does not
* acknowledge it in time.
*/
do {
ret = apple_pmp_report_entry_sleep(ent, false);
} while (ret == -ETIMEDOUT && ++tries < 3);
if (ret)
dev_err(dev, "request %u not asserted after sleep: %d\n", ent->id, ret);
else if (tries)
dev_warn(dev, "request %u asserted after sleep on write %d\n", ent->id,
tries + 1);
return ret;
}

static const struct dev_pm_ops apple_pmp_report_entry_pm_ops = {
NOIRQ_SYSTEM_SLEEP_PM_OPS(apple_pmp_report_entry_suspend_noirq,
apple_pmp_report_entry_resume_noirq)
};

static int apple_pmp_report_entry_power_on(struct generic_pm_domain *genpd)
{
return apple_pmp_report_entry_set_state(genpd, true);
Expand Down Expand Up @@ -1440,6 +1517,7 @@ static int apple_pmp_report_entry_probe(struct platform_device *pdev)
}
ent->no_ack = of_property_read_bool(node, "apple,no-ack");
}
ent->sleep_release = of_property_read_bool(node, "apple,release-for-sleep");

ret = of_property_read_string(node, "label", &name);
if (ret < 0) {
Expand Down Expand Up @@ -1521,6 +1599,7 @@ static struct platform_driver apple_pmp_report_entry_driver = {
.driver = {
.name = "apple-pmp-report-entry",
.of_match_table = apple_pmp_report_entry_of_match,
.pm = pm_sleep_ptr(&apple_pmp_report_entry_pm_ops),
/* Power-domain providers are not intended for manual unbinding. */
.suppress_bind_attrs = true,
},
Expand Down
Loading